Liquid Theme Indirect Tracking
How it works
Indirect tracking connects a purchase on your Shopify store back to the Funneled funnel that influenced it — even when the customer leaves and comes back later through a different channel.
- A customer visits one of your funnel pages
- Funneled sets a tracking cookie on your root domain
- The customer returns to your Shopify store later (via Google, direct, email, etc.)
- The attribution script on your store reads the cookie and links the visit back to the funnel
- When the customer checks out, Funneled records the conversion in your analytics
Funneled can install this automatically. Use this guide if you prefer to add the script manually or if your theme setup requires it.
Prerequisites
Your storefront must share a root domain with your funnel subdomain — the _gf_attr cookie is scoped to it.
| Funnel subdomain | Store domain | Works? |
|---|---|---|
pages.acme.com | acme.com | Yes |
pages.acme.com | shop.acme.com | Yes |
pages.acme.com | mystore.myshopify.com | No — different root domains |
Step 1 — Create the snippet
In your Shopify admin, go to Online Store → Themes → Edit code. Under the Snippets folder, create a new snippet called funneled-indirect-tracking.liquid and paste the following:
{% comment %}
Funneled indirect attribution — loads the attribution script from
your funnel subdomain. The script reads the _gf_attr cookie and writes
funnel/session IDs to Shopify cart attributes via the AJAX Cart API.
{% endcomment %}
{% unless request.design_mode %}
<script src="https://YOUR_FUNNEL_SUBDOMAIN/attribution.js?shop={{ shop.permanent_domain }}" defer></script>
{% endunless %}Replace YOUR_FUNNEL_SUBDOMAIN with your actual funnel subdomain (e.g. pages.acme.com). Leave {{ shop.permanent_domain }} as-is — Shopify replaces it at render time with your store's *.myshopify.com domain:
<script src="https://YOUR_FUNNEL_SUBDOMAIN/attribution.js?shop={{ shop.permanent_domain }}" defer></script>The ?shop={{ shop.permanent_domain }} query parameter mirrors what Shopify's ScriptTag API appends automatically on auto-installed stores, so manual installs stay consistent with the rest of the platform.
You can find your funnel subdomain in Funneled → Settings → Domain.
Why defer?
The defer attribute tells the browser to download the script in parallel with parsing and execute it only after the DOM is ready. The script itself further defers its work with requestIdleCallback, so it never competes with rendering or user interaction.
Step 2 — Render the snippet in your layout
Open your theme's main layout file — typically layout/theme.liquid — and add the snippet render just before the closing </body> tag:
...
{% render 'funneled-indirect-tracking' %}
</body>
</html>Placing it at the end of the body ensures it doesn't block anything above it. Combined with the requestIdleCallback deferral inside the script, the attribution logic runs only after the page is fully rendered and idle.
WARNING
Do not place the render tag inside <head>. Although the script defers its work, placing it in the head delays parsing of everything below it.
Performance
The script is designed to add zero perceptible overhead to your store. It loads after your page content, defers its work until the browser is idle, and only runs once per funnel session. It does not execute inside the Shopify theme editor.
Verify the integration
- Visit a funnel page on your subdomain.
- Navigate to your Shopify store and place a test order.
- In Shopify Admin → Orders, open the order and confirm Funneled attribution data appears in the order's note attributes.
If attribution isn't appearing, check that your funnel subdomain and store share the same root domain (see Prerequisites above). You can also confirm the snippet is rendering by searching your page source for attribution.js.
Remove the script
Delete the {% render 'funneled-indirect-tracking' %} line from your layout, then delete the funneled-indirect-tracking.liquid snippet file. No other cleanup is needed — the tracking cookie expires on its own.
Disable indirect tracking
Toggle off from Funneled → Settings → Attribution. The widget stops writing the tracking cookie and the snippet becomes a no-op.
