Introduction
What is the best predictor of purchase / subscription for consumer products? In analysis after analysis, i have found the same answer – Engagement.
And it makes sense. Users pay for games that they like playing; they pay for tools that they use regularly; they take subscriptions for services that they find useful during free trial.
For Shopify stores, visitors make a purchase after engaging with your store – reading reviews, exploring collections, loving your brand story. All of this can be measured through engagement.
GA4 Events are bad for tracking engagement
GA4-Shopify integration provides excellent events for measuring visitors, pageviews, the whole purchase journey from add to cart to purchase.
But GA4 does not provide good events for measuring engagement on the site. Let’s see what we get in GA4 –
- user_engagement event provides time spent on the website
- scroll provides a way to measure users going to the bottom of the page
- video_* events provide a way to measure video plays on the website
- form_* events provide a way to measure form fills
Apart from user_engagement, other events are impacted by 3rd party apps. For example, an app for adding short videos on the store triggers a video_start event when user clicks on a video, but does not trigger the event if you go from one video to next.
This is not a major issue because you can easily setup engagement events with GTM – Google Tag Manager. You can also add the GTM/GA4 id to some 3rd party apps and get data from them. Here are events you can (and should) measure through GTM:
- click events to measure product card clicks, blog and video clicks, menu selections, etc.
- click events for variant selection on PDP, for product details, etc.
- visibility events to measure if users have seen certain sections like review, FAQs, description, etc.
- custom scroll values at multiple thresholds to get a better idea of engagement (default is 90% depth)
- 3rd party data for searches, video engagement, chatbot engagement etc.
I will cover this in detail in a series on GTM. In this post, I will stick to the default events which do not measure any of the above.
Before you skip this post because you don’t have GTM setup (it is super easy though), let’s look at user_engagement – the single most important engagement event.
Also, the model given in this post will work well with all the additional events whenever you get around to implementing them on your store. So your effort will not be wasted.
Events
Event: user_engagement
Trigger: When visitor has engaged with the store in on the following ways-
- visitor has spent over 10 seconds on the store
- visitor has done 2 interactions on the site – clicks, form fills, video plays, etc.
- user has triggered a ‘key event’ – like add to cart
This event triggers multiple times on a page if visitors stays on the page. This makes it very useful in measuring time-spent by user on a page and in the entire session. (Other analysts have different experience here so do check how it works in your setup).
For stores, this event has one primary use – to calculate engaged sessions and pageviews.
Shopify Stores get majority of visits through marketing and a lot of this traffic does not engage – it bounces. This makes ‘bounced session’ a very important KPI.
Apart from this, the event tracks time spent by user on a page (or on the store during a session). This is because the event triggers every few seconds while a visitor is going over the details of the page – either just scrolling and reading, or clicking on reviews, product description etc.
Note: If you have GTM setup and you track all these small interactions, you don’t need to rely on the user_engagement event alone because each user interaction comes with a engagement_time_msec which contains the time elapsed since last user interaction in milliseconds.
Metrics calculated with user_engagement event –
- engaged sessions: a session with user_engagement event is tagged as engaged.
- engaged page-views: a page with user_engagement event is tagged as engaged. A session can have multiple engaged page-views.
- bounced sessions: a session without user engagement event, and without any other non duplicate page-view is a bounced session.
- time on page: total time on page, calculated by adding up ‘engagement_time_msec’ field from ALL the events triggered on a page. Can also be calculated as difference of page load ts of current page and next page, or current page and session end (if current page is last page)
- time on site: total time spent by a user in a session, calculated by adding up ‘engagement_time_msec’ field from ALL the events triggered on a page. Can also be calculated as difference of session end and session start timestamp.
In google analytics reports, this event shows up in engaged sessions and average time metrics for page reports.
Event: scroll
Trigger: scroll is triggered when users have scrolled to a specified depth on the website.
Be default GA4 settings, ‘scroll’ only triggers at 90% depth – close to the bottom of the page. This is not very useful. You can trigger scroll event more often by setting it up through GTM.
This event has become less useful because of various reasons – like sticky CTAs at the bottom of the page which trigger the event even when the user is at the top. If you are getting scroll for most of your traffic (even for bounced traffic), it’s clearly buggy.
However, if you are getting the event correctly, use it to get a better sense of engagement on your pages.
You can setup visibility events on GTM as an alternative to scrolls. With these, you can directly measure what percentage of users saw a particular section of the page.
view_search_results
Trigger: when users use the search widget on the store.
While the event is useful, it’s easier to get the data from the URL itself using regex statements. If you use a 3rd party app for search, it will give you detailed events for searches.
form_start
Trigger: when users click on a form field.
form_submit
Trigger: when users submit a form.
click
Trigger: when users click on a outbound link – something that takes the user away from the website.
video_start
Trigger: when visitor plays a video on your store.
Use this to measure video plays for videos embedded on your site – on the blog or about pages.
video_complete
Trigger: when visitor watches a video to the end / or brings it to the end.
video_progress
Trigger: multiple times during a video play. Can be used to calculate how long the video was played.
file_download
Trigger: on file download.
Data Models
Model: navigation
Description: This model uses engagement events to understand how visitors are going from one page to another on the store.
| Column Name | Description |
|---|---|
| unique_page_id | user_id + ga_session_id + page_location + page_load_ts |
| date_ist | Data of event, in IST. Data model is partitioned on this column. |
| user_id | unique identifier of the user |
| ga_session_id | unique session identifier for the user |
| page_location | URL of the page, cleaned of extra parameters. Referred below as ‘current page’ |
| page_load_ts | timestamp, in microseconds, of page load |
| Next_page_loc | URL of the next page visited by the user, cleaned of extra parameters |
| next_page_ts | Timestamp, in microseconds, of next page load |
| event_counter | counter to uniquely identity events in a session. |
| trigger_event | Event that triggered the next page load. Only available for GTM based click tracking. |
| Page_referrer | Page_referrer of the current page |
| Next_page_referrer | Page_referrer of the next page. |
| Match_rank | A numeric value corresponding to matching type. This is used for de-duplication. (Refer to query for more details) |
| Matching_type | Matching Type, assigned on the basis of page referrer values and trigger_event. |
Table with details of Matching Type
| Matching Type | Description |
|---|---|
| Event and referrer | The event and the page referrer are aligned and match. |
| Event only | the event is correct for the page change but the page referrer value doesn’t match. Happens because many events don’t give the correct value for page referrer. Mostly happens with 3rd party events. |
| Event missing | There is a page change and the page referrer shows the same. But there is no event connecting the pages. Could be because the event is not logged. Or we have not placed a event in GTM to capture this click/link click. |
| Back button | When user returns to a previous page using the back button. |
| External link | When user opens two pages from google search / meta ad or links then it’s tagged as external traffic from one to next page. |
| Referral missing | This happens when next_page_loc does not have a referrer. This implies user entered the URL for the next page and landed on it. |
| Same previous tab | This implies user opened two tabs from the same tab (like two products from a collection) and then visited those pages one by one. |
| Checkout flow | When user goes from checkout flow to a page, we don’t get events. Hence they are tagged together into one group. |
The below model is just one of many you can build with engagement events. These models only make sense if you have setup additional events through GTM. Otherwise, you won’t be getting much here.
You can build similar models for collection page, home page, blogs and any other major page type on your store. Note that the item details are taken from view_item event which we will see in the next post.
Model: product_page_actions
Description: This model contains all the events triggered on a PDP. In addition, it contains details about the PDP taken from view_item event. In the query, you can add more fields from event_parameters and items_array to the model below as per your data needs.
| Column Name | Description |
|---|---|
| unique_key | user_id + ga_session_id + event_timestamp + event_counter |
| user_id | unique identifier of the user |
| ga_session_id | unique session identifier for the user |
| page_location | URL of the product page, cleaned of extra parameters. |
| page_load_timestamp | time, in micros, of page load |
| page_num | page in sequence |
| event_timestamp | Timestamp, in microseconds, when the event triggered |
| event | Name of the event |
| engagement_time_msec | milliseconds since last event |
| item_variant_id | Unique identifier of the variant of the product |
| item_product_id | Unique identifier of the product |
| item_name | Name of the item and variant in a single string (Water, 200 ml) |
| item_price | Price of the item-variant in Store’s currency |
| item_category | Category of the item – if assigned. |
Next Steps
Compared to the rest of this series, this post is underwhelming, at best. This is perhaps the biggest limitation of GA4 events, and the strongest use case for investing some time into GTM.
However, there is one engagement event we haven’t discussed here – the most important one – add_to_cart. It’s so vital that the next post is entirely dedicated to it.

Leave a Reply