How to Track Shopify App Installs by Source: A GA4 and BigQuery Walkthrough
To track Shopify app installs by source, you have to solve one specific problem. A merchant clicks Add app and leaves your listing. They pass through Shopify's OAuth flow, which breaks the referrer chain. The install then arrives with no memory of where it came from.
This is why so many developers open GA4 and find every install labelled direct. The paid campaign, the blog post, the partner referral: all of it collapses into one bucket. Shopify's own developer forums carry open threads on exactly this.
This guide walks through the exact setup, in order. Where the chain breaks, what to configure, which event fires and what it contains, what gets joined to close the gap, and what the finished report looks like. A comparison of alternative methods sits near the end for teams who cannot use the full setup.
TL;DR
|
Question |
Quick answer |
|---|---|
|
Why do installs show as direct in GA4? |
The Add app button routes through Shopify OAuth, which drops the referrer before the install lands on your side. |
|
What actually fixes it? |
A GA4 property on your listing, a Measurement Protocol API secret, and a BigQuery export joined to install events. |
|
What event fires on install? |
shopify_app_install, sent server-side by Shopify via the GA4 Measurement Protocol. |
|
What gets joined? |
The GA4 client ID and session data from the listing visit, joined to the install event and your own subscription records. |
|
Where do UTMs go? |
On every inbound link pointing at your listing URL, before the merchant ever reaches Shopify's OAuth flow. |
|
What good looks like |
A report showing source, sessions, Add app clicks, installs, and retention, all in one row per channel. |
Why Install Attribution Breaks on Shopify
Understanding the break point makes every fix downstream obvious. Here is the actual journey a merchant takes.
|
Stage |
Where it happens |
What is tracked |
|---|---|---|
|
Merchant sees your ad or blog post |
Your channel |
UTM parameters, if you set them |
|
Lands on your App Store listing |
apps.shopify.com |
GA4 session, if analytics is connected |
|
Clicks Add app |
apps.shopify.com |
A GA event, if you configured one |
|
Passes through Shopify OAuth |
Shopify |
Nothing you control |
|
Install completes on your app |
Your app |
The install event, with no referrer |
[Diagram: five-stage flow from ad click through OAuth to completed install, with a break marked at the OAuth stage. Insert as a labeled flowchart image.]
The Walkthrough: Setting Up Install Attribution
Seven steps, in order. Each one includes exactly where to click and what you should see once it works.
Step 1: Add a UTM-tagged link, not a bare one
Before anything else, decide the UTM structure you will use on every link pointing at your listing. A consistent pattern matters more than any particular naming choice.
https://apps.shopify.com/your-app-handle?utm_source=newsletter&utm_medium=email&utm_campaign=aug_launch
Use that pattern on every inbound link: blog posts, ads, partner referrals, social. Anything without a UTM arrives looking identical to organic traffic once it hits the listing.
Step 2: Add GA4 to your Shopify App Store listing
In your Shopify Partner Dashboard, open your app, go to Distribution, then Manage listing. In the Tracking information section, enter your GA4 Measurement ID. This is the starting point; without it, none of the following steps have anywhere to send data.
[Screenshot: Partner Dashboard, Distribution tab, Tracking information section with the Measurement ID field visible.]
Step 3: Create a Measurement Protocol API secret
In GA4, go to Admin, then Data Streams, and open the same stream used for your listing. Click Measurement Protocol API secrets, then Create. This secret is what lets Shopify send the install event server-side, which Shopify's own developer documentation confirms this is required to receive install-level events at all.
[Screenshot: GA4 Admin, Data Streams, Measurement Protocol API secrets panel with the Create button visible.]
Step 4: Add the API secret back to your listing
Return to the Tracking information section in your Partner Dashboard and paste in the API secret. Save. From this point forward, Shopify can send the shopify_app_install event whenever a merchant completes an install.
Step 5: Verify the event is firing
Open GA4's Realtime report and complete a test install, or watch for the next real one. You should see shopify_app_install alongside the client-side events Shopify already sends by default. These include add app button and open app button clicks.
|
Event name |
Fires when |
Sent how |
|---|---|---|
|
add app button |
Merchant clicks Add app on the listing |
Client-side, automatic |
|
open app button |
Merchant opens the app after install |
Client-side, automatic |
|
shopify_app_install |
Install completes, after the OAuth redirect |
Server-side, via Measurement Protocol |
A known issue worth checking for: developers on Shopify's community forums have documented cases where the ga_session_id attached to the shopify_app_install event does not match the actual browser session. If your install count in GA4 looks right but the source attribution looks wrong, this is a likely cause. It is not a setup mistake on your end.
Step 6: Create a Google Cloud project and enable BigQuery
Create a new Google Cloud project, or use an existing one, then enable the BigQuery API. This is the destination for the raw, event-level data that the GA4 interface cannot give you directly.
Step 7: Link GA4 to BigQuery and join the data
In GA4, go to Admin, then Product Links, then BigQuery Links, and connect your Google Cloud project. Once the export is running, each listing visit and each install exists as a queryable row. Both are joinable on the GA4 client ID and session identifiers.
[Screenshot: GA4 Admin, Product Links, BigQuery Links configuration screen.]
What Actually Gets Joined
This is the part most guides skip. Once data lands in BigQuery, here is what a join looks like in practice.
|
Field |
Comes from |
Used to |
|---|---|---|
|
client_id |
GA4 session on the listing visit |
Link a visit to a later install event |
|
session_source / session_medium |
UTM parameters or referrer |
Attribute the visit to a channel |
|
shop_id (custom dimension) |
Shopify, sent with app events |
Tie the GA4 record to a specific merchant |
|
Install timestamp |
shopify_app_install event |
Anchor the install in the funnel sequence |
|
Subscription and retention data |
Your own app's records, not GA4 |
Extend attribution past install into retention |
The last row is the step that turns raw attribution into something decision-worthy. GA4 and BigQuery can tell you which channel produced the install. Only your own subscription data can tell you which channel produced a merchant who stayed.
What the Finished Report Looks Like
Once the join is running, a source-level report should look roughly like this. Numbers below are illustrative, not benchmarks.
|
Source |
Sessions |
Add App Clicks |
Installs |
Day-30 Retained |
|---|---|---|---|---|
|
App Store search: "inventory sync" |
1,240 |
310 |
96 |
61 |
|
Partner referral: agency-x |
180 |
88 |
41 |
33 |
|
Newsletter: aug_launch |
620 |
140 |
52 |
22 |
|
Direct / unattributed |
890 |
205 |
77 |
29 |
Read that table the way a team actually should. The newsletter campaign produced more installs than the agency referral. The agency referral, though, retained roughly 80% of installed merchants against roughly 42% for the newsletter. Ranked by installs alone, the newsletter wins. Ranked by retained merchants at day 30, the agency referral wins by a wide margin. That is the entire reason source-level retention, not just installs, is the number worth building toward.
Other Attribution Methods, If You Cannot Run the Full Setup
The walkthrough above is the complete path. If BigQuery is not available to you yet, these are the partial methods. Here is what each one gets you, and where each one stops.
|
Method |
What it captures |
Where it stops |
|---|---|---|
|
GA4 on the listing only |
Page views and traffic sources reaching your listing |
No install-level data at all |
|
UTM parameters alone |
Which of your own channels drove the visit |
Cannot tag Shopify Ads or organic App Store search |
|
Add app click events |
Intent to install and listing conversion rate |
A click is not a completed install |
|
Partner dashboard referrers |
Broad referrer categories from Shopify |
Low granularity, no campaign detail |
|
Custom OAuth state parameter |
Passes limited data through the redirect |
Engineering work, fragile, easy to break |
These are worth doing regardless. Each one is free, and each one tells you something about the funnel up to the click. None of them, individually, get past the OAuth break. Only the GA4-to-BigQuery join in the walkthrough above does that.
Skipping the Maintenance: Elevate
Everything above is a one-time setup, but it is not a one-time maintenance cost. Schema changes, GA4 updates its own interface periodically, and the SQL joining sessions to installs needs upkeep.
Elevate connects to the same Google Analytics and BigQuery data alongside your Shopify Partner account. It produces the Install Funnel and Traffic Source Insights views without any query writing. Because install source sits alongside subscription data in the same system, the retention column in the sample report above is already there. See Elevate for the full setup.
[Image alt text: install funnel view showing how to track Shopify app installs from page views through to completion]
Pair install source with merchant lifetime value to see which channels produce high-LTV merchants, or with customer health scoring to spot sources that deliver installs which never activate. For teams running several apps, multi store analytics rolls attribution up across the whole portfolio. And once you know which channels bring merchants, Shopify App Discovery covers the channels themselves in more depth, while Merchant Success covers how marketing, product, and support teams act on this data together.
Frequently Asked Questions
How do I track Shopify app installs by source?
Add a GA4 property and a Measurement Protocol API secret to your listing, and tag every inbound link with UTM parameters. Then export GA4 to BigQuery and join session data to the shopify_app_install event.
Why do all my installs show as direct in GA4?
The Add app button routes merchants through Shopify's OAuth flow, which drops the referrer before the install completes. GA4 sees a new session with no source and labels it directly.
What event does Shopify send when an app is installed?
shopify_app_install, sent server-side through the GA4 Measurement Protocol. It arrives alongside client-side events like add app button and open app button, which fire automatically once GA4 is connected.
Why does my install source data look wrong even though the event fires?
Check the ga_session_id on the install event. Developers have documented cases on Shopify's community forums where this ID does not match the browser session that actually visited the listing. That breaks attribution even though the event itself arrives correctly.
Can I track Shopify Ads installs separately from organic?
Not directly. Shopify Ads placements cannot carry your own UTM parameters, so paid and organic App Store traffic look identical. You can only cleanly attribute channels you control yourself.
Why use BigQuery instead of reading GA4 directly?
GA4's interface reports aggregated sessions and cannot join them to install events that happen off-platform. The BigQuery export gives you event-level rows, which you can join to install and subscription records.
How far back does listing tracking go once I set it up?
Not retroactive. GA4 records traffic only from the moment the property is connected to your listing. Enable it before your next campaign rather than after.