Shopify SEO. Measurement

Shopify GA4 Audit: Prove the Funnel Works Before You Judge SEO

107 vs 1,587Cart adds against purchases, same four weeks
2 IDsMeasurement IDs on one store, each fed different events
0Times item_list_name appeared on collection pages
1.7%Engagement rate of US blog sessions on an Indian store

Written by Ram Kr Shukla, SEO and growth consultant, Google Analytics certified.

Quick answer

If your Shopify GA4 tracking isn’t working, one test proves it fast. Pull view_item, add_to_cart, begin_checkout and purchase for the same 28 days, as event counts and as users. Each step must be larger than the next. If add_to_cart comes in below purchase, the funnel’s broken, whatever a one day screenshot says. Then check which measurement IDs receive which events, whether collection pages send item_list_name and item_list_id, and how much of your traffic is bots. Until all four checks pass, judge SEO on Search Console clicks and GA4 landing page sessions.

Here’s the number that ended an argument. Over four weeks, an Indian cosmetics store I audited recorded 107 add_to_cart events in GA4. Over the same four weeks it recorded 1,587 purchases.

You can’t buy more things than you put in a cart. Not fifteen times more.

The store’s tech team pushed back anyway. They sent a screenshot with add_to_cart at 31 and said tracking was fine. Their screenshot covered a day or two. My numbers covered 28 days, with view_item, add_to_cart, begin_checkout and purchase side by side. Once everyone looked at the same window, there wasn’t anything left to debate, and the fix shipped.

This is the audit I now run on any store before I use its GA4 data to judge SEO. It sits inside my Shopify SEO work, and it’s deliberately hands on: eight checks, what each looks like when it fails, and what to measure SEO on while it’s broken. If you want the reporting layer that sits on top of clean data, read what a real Shopify SEO report contains and how to read an e-commerce SEO report without being fooled. This post is about whether the numbers underneath are true.

Why SEO Gets Judged on Broken Data

Most SEO verdicts on a Shopify store lean on GA4 somewhere. Did the new collection copy lift cart adds? Did the blog help any orders? Does organic convert better than paid? Every one of those questions assumes the events fire, land in the property you’re reading, and carry the parameters that say where they came from.

On the store above, none of that held at the start. view_item recorded 901 events from 170 users in four weeks. That’s on a store doing thousands of orders a month. Any page level conclusion drawn from that window would’ve been fiction, and some had already been drawn.

GA4 doesn’t warn you. Reports load, charts look normal, and purchases look plausible. On this store checkout ran through a third party checkout app whose events fired correctly the whole time, so the bottom of the funnel looked healthy while the top was nearly empty. Nobody noticed until someone tried to credit a page.

Already suspicious of your organic numbers for other reasons, like untagged paid traffic or parameters rewriting the source? That’s a separate problem, covered in why your organic traffic numbers are lying to you. This audit checks the ecommerce events themselves.

What Shopify’s Google & YouTube App Should Be Sending

You can’t call something missing until you know what should be there. If GA4 is connected through Shopify’s Google & YouTube app, Google’s reference for the app’s event parameters lists these events, mapped from Shopify’s own standard customer events such as product_viewed, product_added_to_cart and checkout_completed.

GA4 eventWhat it recordsFunnel role
page_viewAny page viewTraffic
view_item_listA collection page viewDiscovery
view_itemA product page viewStep 1 of the test
add_to_cartA product added to the cartStep 2 of the test
remove_from_cartA product removed from the cartContext
view_cartA cart page viewContext
begin_checkoutCheckout startedStep 3 of the test
add_shipping_infoShipping or address details enteredCheckout progress
add_payment_infoPayment details enteredCheckout progress
purchaseOrder completedStep 4 of the test
searchA storefront searchContext

Event list from Google’s Shopify event parameter reference. The funnel role column is how this audit uses each one.

Three details on that page matter for the audit.

  • Some events are newer than your history. Google’s Shopify setup help page says the app now sends view_item_list, remove_from_cart, view_cart and add_shipping_info, and adds new data to five events it already collected. A gap in older months might just be the period before those events existed.
  • Every event carries a shopify_event_name parameter. Google suggests using it to filter the newer event data out of reports if you need to. It’s also handy for telling app events apart from ones a theme script or GTM sends with the same GA4 name.
  • select_item isn’t on the list. In Google’s ecommerce measurement guide, select_item is the click from a list to a product, and item_list_id and item_list_name ride on the items in select_item and add_to_cart. If the app doesn’t send select_item, that link has to come from a custom pixel or GTM.

Two platform rules also explain a lot of “it worked in the old theme” complaints. Shopify runs app pixels and custom pixels in a sandbox that can’t pick up events by scraping the page, and in markets that need consent, pixels run only after the visitor grants it (see Shopify’s pixels overview). Separately, on the store I audited, the add to cart buttons inside blog product blocks sat in a shadow DOM. A GTM click trigger built on a CSS selector would never have seen them.

The One Line Test: Every Step Bigger Than the Next

Here’s the whole test. Over the same 28 days, view_item has to be larger than add_to_cart, which has to be larger than begin_checkout, which has to be larger than purchase. Check it twice: once on event count, once on users. The free GA4 funnel checker runs this test on your own numbers, right in your browser.

Here’s how that store looked in two consecutive four week windows.

EventBroken windowAfter the fix
view_item901 (170 users)413,745 (69,609 users)
add_to_cart107 (56 users)71,762 (24,539 users)
begin_checkout3,99122,656 (15,479 users)
purchase1,587about 7,200

Event counts, with total users where captured. Anonymised client data.

Same four events, two four week windowsBar length is relative to the largest step in each window.BROKEN WINDOWview_item901add_to_cart107begin_checkout3,991purchase1,587add_to_cart sits about 15 times below purchase. Impossible.AFTER THE FIXview_item413,745add_to_cart71,762begin_checkout22,656purchaseabout 7,200Every step smaller than the one before. Passes.RamKrShukla.comIllustrative. Anonymised client data.
One D2C beauty store, two consecutive four week windows. In the first, three of the four steps are out of order. After the fix, each step is smaller than the last.

In the broken window, three things fail at once. add_to_cart is about 15 times below purchase. begin_checkout is about 37 times above add_to_cart. And 170 users viewing products can’t produce 1,587 orders.

After the fix, the order holds. Roughly 17% of product view events led to a cart add event, 32% of cart adds to a checkout, and 32% of checkouts to a purchase. I wouldn’t treat those ratios as a benchmark for your store, because price point, traffic mix and buy it now buttons all move them. The test is about order, not size.

Why the one day screenshot lost the argument

The tech team’s screenshot wasn’t faked. add_to_cart really did show 31 on the day they picked. It still proved nothing, for three reasons.

  • The window was too short. A day or two of data swings with campaigns, sales and weekends. A tag that fires for one shopper in twenty still produces a non zero number on any given day.
  • It showed one event alone. 31 cart adds means nothing until you see purchases for the same day next to it.
  • It didn’t match the window being discussed. My 107 covered 28 days. You can’t rebut a 28 day number with a one day number.

So the rule I give every client now: never send one event in isolation. Always send all four funnel events together, last 28 days, events and users. It turns a debate into a reading.

The legitimate exceptions, and their limits

A funnel can bend for real reasons. Shopify’s dynamic checkout buttons let shoppers skip the cart and go straight to checkout, so on a store where most buyers tap Buy it now, begin_checkout can sit close to add_to_cart or even above it. Checkout links in emails or ads skip the product page too.

Those explain a narrow gap. They don’t explain purchase at fifteen times add_to_cart on a store where the cart is the main path. If you suspect the buy now path, put a test order through it in DebugView and see which events it fires. Then you’ll know how much of the gap it can account for.

The opposite failure matters too. A step that’s suspiciously high, like purchase above begin_checkout or page_view doubling overnight, usually means two tags counting the same action. Google warns that a single action can be counted more than once when several Google tags are set up, or when tracking existed before the Google & YouTube app went in.

How to Audit Shopify GA4, Step by Step

Run these in order. Each one depends on the window and the property you fixed in the steps before it.

1

Fix one 28 day window

Pick the last 28 complete days and use that exact range for every number in the audit. If ecommerce tracking went live partway through, start the window after that date, or every step will look short.

2

Pull four events as counts and users

In GA4, open Reports, Engagement, Events, or build a free form exploration with Event name as the row and Event count plus Total users as values. Pull view_item, add_to_cart, begin_checkout and purchase together. Never one event on its own.

3

Run the order test

Each step has to be larger than the next, on events and on users. If add_to_cart is lower than purchase, or view_item users look like a rounding error next to your order count, the upper funnel is broken.

4

List every measurement ID on the site

Open a collection page, a product page and a blog post with Tag Assistant connected and note every G- ID that loads. Then check Admin, Data streams in the GA4 property you actually report from, so you know which ID feeds it.

5

Map which events reach which ID

Add a product to the cart, view the cart and start checkout while Tag Assistant is recording. Write down, event by event, which measurement ID received it. A grid with events down the side and IDs across the top is enough.

6

Check the item list parameters

Search the page source and dataLayer of a collection page for item_list_name and item_list_id, and check whether select_item ever fires. In GA4, an Item list name dimension that reads (not set) everywhere tells you the same thing.

7

Strip out the bots

Break blog and landing page sessions down by country, with engaged sessions, engagement rate and average engagement time next to them. Rows with thousands of sessions, an engagement rate near 1 percent and a few seconds per session aren’t shoppers.

8

Confirm the fix and re-run after 28 days

Place a test order in DebugView and watch each event arrive with its items. Then wait a full 28 days after the fix ships and run the order test again on that clean window before you let anyone judge a page on it.

For step 2, a funnel exploration set to an open funnel gives you the same four steps as a chart, but the plain event table is quicker to screenshot and harder to argue with. For step 8, Google’s DebugView guide covers turning on debug mode through Tag Assistant.

Two Measurement IDs, Two Different Funnels

Steps 4 and 5 found the second big problem on that store. Its collection pages carried two GA4 measurement IDs. Blog pages carried a third. Inside the store’s Google pixel settings, events were mapped to IDs one by one, and the mapping wasn’t the same for every event.

EventID AID B
page_viewYesYes
add_to_cartYesYes
add_payment_infoYesYes
view_item_listYesNo
view_cartYesNo
add_shipping_infoYesNo

Read from the store’s pixel settings. Real IDs replaced with letters.

One store, two measurement IDsWhich events reached which ID, read from the store’s pixel settings.page_viewadd_to_cartadd_payment_infoview_item_listview_cartadd_shipping_infoMeasurement ID Areceives all 6Measurement ID Breceives 3 of 6sent to both IDssent to ID A onlyIf your reports read ID B, collection list views never arrive.RamKrShukla.comIllustrative. Anonymised client data.
Six events, two IDs. Cart adds reached both, collection list views reached only one. IDs replaced with letters.

Think about what that does to a report. If the property you read is fed by ID B, collection page product impressions never arrive, while cart adds from those same pages do. Collections look like they sell without ever being seen. Any SEO conclusion about collection pages from that property is built on a hole.

One pattern worth checking on your own store: view_item_list, view_cart and add_shipping_info are three of the four events Google lists as newer additions to the app. When events get added later, it’s easy for them to be mapped to one destination and not the other. That’s a hypothesis to test in step 5, and I haven’t proven it’s why this store split.

The fix is mostly a decision. Pick the property you report from and send every ecommerce event to its measurement ID. A second ID can stay if someone can say who reads it and why. Write that down, because the next agency or developer will add a third.

Item List Parameters: Why Collection Pages Can’t Get Credit

This is the check most audits skip, and it’s the one that decides whether collection SEO can ever be proven in GA4.

Three pieces work together. view_item_list says a list of products was seen. item_list_name and item_list_id say which list it was. select_item says which product the shopper clicked from that list. When the list name also travels on the items in add_to_cart and purchase, GA4 can tell you which collection, search page or blog block a cart add came from.

On the store I audited, item_list_name, item_list_id and select_item appeared zero times on collection pages. Zero on blog pages too, which had 66 links to product pages on a single post and fired nothing but page_view. So a cart add that started on a complexion product collection looked exactly like one that started on the homepage. Even where view_item_list did land, the list was unnamed.

Google doesn’t join this up for you after the fact. For promotions, its ecommerce setup guide says that to measure a purchase after someone views or clicks a promotion, you add the promotion ID or name to every later ecommerce event. In practice I treat item lists the same way: the list name has to be on the item when the cart add and the purchase fire, or there’s nothing to group by.

What I ask a developer for, in priority order:

  • Fire view_item_list on every collection page and on every blog product block, with item_list_id and item_list_name set. Something like blog_[slug] and Blog: [title] for blog blocks keeps them readable.
  • Fire select_item when a product in a list is clicked, carrying the same list fields.
  • Carry the list fields onto the items in add_to_cart.
  • Persist the list onto the cart line, through line item properties or cart attributes, so the purchase items can carry it too. If checkout runs through a third party app, confirm what survives the handoff before promising list level revenue.

Until that ships, measure collection SEO on Search Console clicks and position, plus GA4 landing page sessions for collection URLs. That’s a real limit, because collections are usually where the money is. On the fashion store in my Shopify SEO case study, collection pages drove more than 70% of organic revenue. For what makes those pages rank in the first place, see Shopify collection page SEO, and for one collection type with its own tracking quirks, influencer and creator collection pages.

Bot Traffic: 1,261 Sessions, 13 of Them Engaged

GA4 already removes traffic from known bots and spiders. You can’t switch that off, and you can’t see how much it removed. So whatever’s in your reports got past that filter, and on a Shopify blog a lot gets past it.

Here’s the blog landing page traffic on the same store, split by country.

CountrySessionsEngagedAvg. timeOrders
United States5,8871.7%3.9 sec0
India (home)87133%89 sec4

Blog landing page sessions. Smaller rows from Singapore, Brazil, Vietnam, Argentina and Romania followed the US pattern, at under 4 seconds each. The full country breakdown, and what GA4 can and cannot filter, is in bot traffic in GA4.

An Indian cosmetics store with almost seven times more US blog sessions than Indian ones, at under four seconds each. Those aren’t shoppers. India was the only segment behaving like people, and its blog conversion rate worked out to about 0.46%, which is an ordinary blog number. Google defines an engaged session as one that lasts longer than 10 seconds, has a key event, or has two or more page views, so a 1.7% engagement rate means 98 sessions in 100 did none of those.

It also wrecks prioritisation. The blog post with the most sessions, 1,261, had 13 engaged sessions at 4.6 seconds. Another post with 233 sessions had 92 engaged sessions at 57 seconds. Rank by sessions and you’d invest in the wrong one. Rank by engaged sessions and the second post wins by a factor of seven.

So for step 7: filter every report to the countries you sell to, and rank pages on engaged sessions. Don’t rank on total sessions at all. If you’re deciding how much to spend on the blog against category pages, blog traffic vs category traffic covers that trade off.

The SEO Metrics to Use While GA4 Is Broken

Some of this takes weeks to fix, and some of it, like query level revenue, can’t be fixed by anyone. You still need to judge SEO in the meantime. These are the numbers I use, in order.

1. Search Console clicks, impressions and position, split brand and non-brand

Search Console doesn’t depend on your tags at all. It’s the cleanest SEO number you have. Split it by brand and non-brand, because brand clicks mostly measure demand that already existed.

SegmentImpressionsClicksCTRAvg. position
Non-brand225,8972,5531.13%7.14
Brand22,6422,50911.08%4.97

Home market only, four weeks. Anonymised client data.

Non-brand pulled ten times the impressions of brand for about the same clicks, at a tenth of the CTR and two positions lower. That gap is the SEO opportunity, and it’s visible without a single GA4 event.

One thing confuses people: brand plus non-brand came to 5,062 clicks against 7,173 for the whole site in the same market. Nothing’s broken. Search Console leaves anonymised queries out of query tables, and drops them entirely once you filter by query, so query rows always sum short of the site total. Quote the split as a ratio. More on why the split matters in branded vs non-branded traffic.

2. GA4 landing page sessions and orders, organic only

Landing page sessions survive most event breakage, because they come from page_view and the session’s source. Filter to Organic Search and your home market, then read sessions and transactions by landing page. Pages that only rank for non-brand terms, like blog posts and most collections, are the closest honest proxy for non-brand SEO value.

3. Channel level orders, labelled as such

On that store, Paid Social was about 75% of home market sessions and 58% of orders. Organic Search was about 3.5% of sessions and 6.4% of orders, with a 4.72% conversion rate against 1.94% for Paid Social. That’s a good organic story. It only stays good if nobody puts Search Console clicks next to all channel GA4 orders on one unlabelled row of scorecards, where every order looks like an SEO result.

What you can’t measure, in any tool

Non-brand revenue. Search Console has the query. GA4 has the session and the order. There’s no key that joins a query to a session, so nobody can tell you which orders came from non-brand searches. Anyone quoting a non-brand revenue figure is estimating, and you shouldn’t agree to a target framed that way.

And prefer transactions to revenue when item data is shaky. After the fix on that store, one product line still showed zero item revenue despite about 1,800 units purchased. Any revenue split by product understated that line. Transaction counts weren’t affected, so the dashboard reports counts.

After the Fix: What to Watch For

Don’t compare the first clean window to the broken one and call it growth. When upper funnel events come back, every period on period arrow in GA4 turns green for a few weeks, because the comparison period was missing data. Wait until both windows sit after the fix before you read a trend. The arithmetic for that date, and what to report until it arrives, is in why GA4 comparisons show fake growth after a tracking fix.

Re-run the order test every month. It’s a few minutes’ work, and it’s the fastest way to spot a theme update, a new app or a consent change that quietly broke a tag. If you’re also running crawls against the store to check templates, throttle them first, or Shopify will start refusing requests: see crawling Shopify without 429 errors.

If you’d rather have someone run this audit and write the developer brief, that’s part of my GA4 conversion tracking work.

Shopify GA4 Audit FAQ

Why is my Shopify GA4 tracking not working?

The usual causes are a second Google tag sending duplicate or partial events, events routed to a measurement ID your reports don’t read, a theme or GTM trigger that can’t see the add to cart button, and consent settings that stop pixels from running. Start with the order test: view_item, add_to_cart, begin_checkout and purchase over the same 28 days. The step that breaks the order tells you where to look.

Why is add_to_cart lower than purchase in GA4?

Because add_to_cart isn’t firing for most shoppers, or it’s going to a different measurement ID. Buy it now buttons that skip the cart can narrow the gap, but they can’t make purchases outnumber cart adds by a wide margin on a store where the cart is the main path. On one store I audited it was 107 cart adds against 1,587 purchases, and the cause was tracking.

Does the Shopify Google and YouTube app send view_item_list?

Yes. Google’s help page for the app lists view_item_list for collection views, along with view_cart, remove_from_cart and add_shipping_info, and its parameter reference shows item_list_id and item_list_name on view_item_list. It doesn’t list select_item, so the click from a list to a product isn’t covered by the app alone.

How do I check which GA4 measurement ID gets which event?

Connect Tag Assistant to your store, then view a collection, open a product, add to cart, view the cart and start checkout. Tag Assistant shows each hit and the destination it went to. Record the result as a grid of events against IDs, then confirm in GA4 Admin, Data streams which ID feeds the property you report from.

Why does Item list name show (not set) in GA4?

Because the events reaching your property don’t carry item_list_name on their items. Either the list events aren’t firing, they’re going to a different measurement ID, or they fire without the list parameters. Until that’s fixed, GA4 can’t tell you which collection or blog block a cart add came from.

How do I filter bot traffic out of Shopify GA4 reports?

GA4 already removes known bots and you can’t see how many it removed, so what’s left got past that filter. Break sessions down by country and look at engaged sessions and engagement time. Filter reports to the countries you actually sell to, and rank pages on engaged sessions instead of total sessions.

Can I measure non-brand SEO revenue in GA4?

No. Search Console has the query and GA4 has the session and the order, and there’s no key that joins a query to a session. Report non-brand clicks, impressions and position from Search Console, and organic orders from GA4, as two separate numbers. Landing pages that only rank for non-brand terms are the closest honest proxy.

How long after fixing tracking can I trust GA4 data?

Give it a full 28 days after the fix ships, then run the order test on that window alone. Any window that includes days before the fix mixes broken and working data, and period on period comparisons will show gains that are really just the tracking coming back.

Tags: Shopify SEOGA4Ecommerce TrackingSEO Reporting

RS

Written by Ram Kr Shukla

SEO and growth consultant with 20+ years in the field across 50+ brands, working as a consultant or Fractional Chief Digital Officer. Google Analytics and Google Ads certified. Audits Shopify measurement before judging any SEO result, and works daily in GA4, Search Console and Looker Studio.

Client Results, Not Claims

5x D2C revenue in 18 months via SEO
10x SaaS trials, zero new blog posts
120K Monthly organic visitors from zero

Free Resource

Steal My 40 Point SEO Audit Checklist

The exact list I run on every paid audit. Score your site in 30 minutes.

Get the checklist →

Is your site invisible to AI search?

Ask ChatGPT to recommend brands in your category. If you are not the answer, we should talk.

Book a Free Strategy Call