hydrogen-analytics
Skill218 starsChanged 8 days agoMITView on GitHub
Guide for adding or reviewing Hydrogen storefront analytics. Use when working with ShopifyScripts analytics, AnalyticsEvent, consent mode, page/product/ collection/search/cart view events, cart update tracking, custom analytics destinations, or framework route-change analytics wiring.
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- Shopify/hydrogenedited, first seen Oct 13, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- Shopify/hydrogen★ 2.2k100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- hydrogen-cart-drawerSkill
- hydrogen-cart-metafieldsSkill
- hydrogen-cart-uiSkill
- hydrogen-collection-browserSkill
- hydrogen-customer-accountSkill
- hydrogen-imageSkill
- hydrogen-local-httpsSkill
- hydrogen-marketsSkill
- hydrogen-moneySkill
- hydrogen-oxygenSkill
- hydrogen-predictive-searchSkill
- hydrogen-request-handlersSkill
- hydrogen-routingSkill
- hydrogen-setupSkill
- hydrogen-shop-paySkill
- hydrogen-smoke-testSkill
- hydrogen-storefront-clientSkill
- hydrogen-variant-formSkill
- remix-storeSkill
- testing-practicesSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 28
Read one browser-lazy singleton from the Shopify global created by ShopifyScripts:
- Very specific: line 50
Read shop and i18n values on the server and pass them to ShopifyScripts.
- Distinctive: line 76
Do not dispatch server-side analytics through this browser bus.
- Distinctive: line 77
Keep ShopifyScripts i18n aligned with the resolved market when the storefront uses markets.
- Distinctive: line 85
No browser module reads private or server-only env variables.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Storefront Analytics
Hydrogen's analytics bus owns the event API, event normalization, and consent-gated destination replay. ShopifyScripts owns Shopify consent setup and analytics CDN loading. App code owns when to publish route/view events and when to call cart delta tracking.
Framework References
Before wiring route events, check whether this skill has a reference file for the app's framework in references/. If one exists, read it and use that framework's route-change and lifecycle primitives. If there is no matching reference, keep the core singleton below and adapt page-view, product-view, collection-view, search-view, and cart tracking to the app's own route lifecycle.
Prerequisite: analytics depends on the same-origin SFAPI proxy (see hydrogen-request-handlers) so the browser can observe tracking values from Storefront API responses. The proxy establishes the backend session cookies needed for analytics and checkout continuity; treat analytics as incomplete until it is wired. Key consent setup: Shopify Customer Privacy controls destination delivery in production. Register event consumers with addDestination(); live delivery and replay require analytics consent. Do not bypass Customer Privacy consent gating in production.
Core Pattern
Render Shopify runtime scripts once from the app root/document head with the same resolved market used by Storefront API requests. Use ShopifyScripts from your framework binding if it exports one, or getShopifyScriptTags() / renderShopifyScriptTags() from core in other framework heads. Pass the shop object matching the ShopifyScriptsShop type, and i18n matching the ShopifyScriptsI18n type and serialize them into ShopifyScripts. — declare them as constants with type annotations to keep errors located close to the source of writing. The analytics bus is created by default; pass analytics only for optional bus configuration such as customData. customData isn't added to events you publish; destinations read it via getConfig().customData. Do not pass market country or language through analytics consent config.
Read one browser-lazy singleton from the Shopify global created by ShopifyScripts:
import {
AnalyticsEvent,
type StorefrontAnalytics,
trackCartAnalytics,
} from "@shopify/hydrogen";
export { AnalyticsEvent };
let bus: StorefrontAnalytics | null = null;
export function getAnalytics(): StorefrontAnalytics | null {
if (typeof window === "undefined") return null;
bus ??= window.Shopify?.analytics ?? null;
return bus;
}
export { trackCartAnalytics };Read shop and i18n values on the server and pass them to ShopifyScripts. Do not read env APIs in browser modules.
In the ShopifyScripts analytics config, channel is optional and defaults to "hydrogen". The "hydrogen" channel is the one that requires storefrontId — it is pulled from the ShopifyScripts shop config into analytics payloads. Headless storefronts pass channel: "headless" in the ShopifyScripts analytics config; the analytics payload then omits storefrontId, but shop.storefrontId itself is still required (pass "0" when the app has no storefront ID).
Publish Events
Publish these from route/page boundaries:
PAGE_VIEWEDon each page transition.PRODUCT_VIEWEDwhen product data is resolved on a product page.COLLECTION_VIEWEDwhen collection data is resolved.SEARCH_VIEWEDwhen a non-empty search term has results metadata.CART_VIEWEDwhen the full cart page or cart drawer is viewed.- Wire cart tracking once per cart store lifecycle with
trackCartAnalytics(cartStore)— React apps use theuseCartAnalytics()hook from@shopify/hydrogen/reactand Vue apps use theuseCartAnalytics()composable from@shopify/hydrogen/vue; both call it with the provider's cart store and clean up on unmount. The tracker subscribes to the cart store itself, skips pending/revalidating/note updates, publishes cart delta events on confirmed cart changes, and returns an unsubscribe function. Call it from a client-only effect (useEffect/onMounted), never at cart-store creation time — it throws whenwindow.Shopify.analyticsis missing (SSR). Do not manually publish cart delta events.
The bus defaults shop from the top-level shop config passed to ShopifyScripts; pass shop in an event payload only when intentionally overriding that configured value. Shopify analytics reads its content language from window.Shopify.locale. It reads the currency of product events from the event price's currencyCode and falls back to window.Shopify.currency.active, which i18n.currency sets. Page, collection, and search views take only the global. When it is unset, Shopify analytics sends them without a currency.
Required product analytics fields include Shopify Product GID, ProductVariant GID when available, title, price, vendor, quantity, and variant title.
Rules
- Let Shopify Customer Privacy control destination delivery in production.
- Initialize one single bus per page lifetime through ShopifyScripts.
- Register event consumers with
addDestination()and use thesubscribefunction provided to its setup callback. - For third-party banners, use
consent: {mode: "custom-banner", setup}and read Custom consent providers for readiness, synchronization, and framework integration. - Render ShopifyScripts before route components publish events.
- Do not dispatch server-side analytics through this browser bus.
- Keep ShopifyScripts i18n aligned with the resolved market when the storefront uses markets.
Verify
- Page view fires on initial load and client navigations.
- Product, collection, search, and cart view events fire once per relevant route data change.
- Confirmed cart data changes flow through
trackCartAnalytics(cartStore)(React/Vue bindings:useCartAnalytics()). - Consent-denied visitors do not deliver destination events.
- No browser module reads private or server-only env variables.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

