Analytics. Provider
Provides a context for tracking page views and cart events to send as analytics data to Shopify. This component is integrated with the Customer Privacy API for consent management. The provider can also be used to connect third-party analytics services through its subscribe and publish system. The useAnalytics hook provides access to the analytics provider context.
You can also listen to a document event for shopifyCustomerPrivacyApiLoaded. It will be emitted when the Customer Privacy API is loaded.
Anchor to propsProps
- Anchor to cartcartcartPromise<CartReturn | null> | CartReturn | nullPromise<CartReturn | null> | CartReturn | nullrequiredrequired
The cart or cart promise to track for cart analytics. When there is a difference between the state of the cart,
will trigger aevent. It will also produceandbased on cart line quantity and cart line id changes.- Anchor to consentconsentconsentConsentConsentrequiredrequired
The customer privacy consent configuration and options.
- Anchor to shopshopshopPromise<ShopAnalytics | null> | ShopAnalytics | nullPromise<ShopAnalytics | null> | ShopAnalytics | nullrequiredrequired
- Anchor to canTrackcan
Trackcan Track () => boolean() => boolean An optional function to set wether the user can be tracked. Defaults to Customer Privacy API's
.- Anchor to childrenchildrenchildrenReactNodeReactNode
React children to render.
- Anchor to customDatacustom
Datacustom Data Record<string, unknown>Record<string, unknown> An optional custom payload to pass to all events. e.g language/locale/currency.
- stringstringdeprecateddeprecated
- Anchor to disableThrowOnErrordisable
Throw On Errordisable Throw On Error booleanbooleandeprecateddeprecated - Deprecated
Disable throwing errors when required props are missing.
Deprecated:Disable throwing errors when required props are missing.
CartReturn
TCart & {
errors?: StorefrontApiErrors;
}StorefrontApiErrors
JsonGraphQLError[] | undefinedJsonGraphQLError
- extensions
Reserved for implementors to extend the protocol however they see fit, and hence there are no additional restrictions on its contents.
{ [key: string]: unknown; } - locations
If an error can be associated to a particular point in the requested GraphQL document, it should contain a list of locations.
{ line: number; column: number; }[] - message
string - name
string - path
If an error can be associated to a particular field in the GraphQL result, it _must_ contain an entry with the key `path` that details the path of the response field which experienced the error. This allows clients to identify whether a null result is intentional or caused by a runtime error.
(string | number)[] - stack
string
Consent
Partial<
Pick<
CustomerPrivacyApiProps,
| 'checkoutDomain'
| 'sameDomainForStorefrontApi'
| 'storefrontAccessToken'
| 'withPrivacyBanner'
| 'country'
>
> & {language?: LanguageCode}CustomerPrivacyApiProps
- checkoutDomain
The production shop checkout domain url.
string - country
Country code for the shop.
CountryCode - locale
Language code for the shop.
LanguageCode - onReady
Called once consent is available and the selected APIs are loaded. If initial consent fails to load, waits for a successful consent update. The returned customerPrivacy API may be available earlier, for example to show a custom CMP.
() => void - onVisitorConsentCollected
Callback to be called when visitor consent is collected.
(consent: VisitorConsentCollected) => void - sameDomainForStorefrontApi
boolean - storefrontAccessToken
The storefront access token for the shop.
string - withPrivacyBanner
Whether to load the Shopify privacy banner as configured in Shopify admin. Defaults to false.
boolean
VisitorConsentCollected
- analyticsAllowed
boolean - firstPartyMarketingAllowed
boolean - marketingAllowed
boolean - preferencesAllowed
boolean - saleOfDataAllowed
boolean - thirdPartyMarketingAllowed
boolean
ShopAnalytics
- acceptedLanguage
The language code that is being displayed to user.
LanguageCode - currency
The currency code that is being displayed to user.
CurrencyCode - hydrogenSubchannelId
The Hydrogen subchannel ID generated by Oxygen in the environment variable.
string | '0' - shopId
The shop ID.
string
CurrencyCode
Supports CurrencyCode from both Storefront API and Customer Account API. The APIs may have different CurrencyCode enums (e.g., Customer Account API added USDC in 2025-10, but Storefront API doesn't support USDC in 2025-10). This union type ensures useMoney works with data from either API.
StorefrontApiCurrencyCode | CustomerAccountApiCurrencyCodeExamples
Example
JavaScript
import {Analytics, getShopAnalytics} from '@shopify/hydrogen'; import {Outlet, useLoaderData} from 'react-router'; export async function loader({context}) { const {cart, env} = context; const cartPromise = cart.get(); return { cart: cartPromise, shop: getShopAnalytics(context), consent: { checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, withPrivacyBanner: true, // false stops the privacy banner from being displayed // localize the privacy banner country: context.storefront.i18n.country, language: context.storefront.i18n.language, }, }; } export default function App() { const data = useLoaderData(); return ( <html lang="en"> <head> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> </head> <body> <Analytics.Provider cart={data.cart} shop={data.shop} consent={data.consent} > <Outlet /> </Analytics.Provider> </body> </html> ); }TypeScript
import {Analytics, getShopAnalytics} from '@shopify/hydrogen'; import {type LoaderFunctionArgs} from 'react-router'; import {Outlet, useLoaderData} from 'react-router'; export async function loader({context}: LoaderFunctionArgs) { const {cart, env} = context; const cartPromise = cart.get(); return { cart: cartPromise, shop: getShopAnalytics({ storefront: context.storefront, publicStorefrontId: env.PUBLIC_STOREFRONT_ID, }), consent: { checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, withPrivacyBanner: true, // false stops the privacy banner from being displayed // localize the privacy banner country: context.storefront.i18n.country, language: context.storefront.i18n.language, }, }; } export default function App() { const data = useLoaderData<typeof loader>(); return ( <html lang="en"> <head> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> </head> <body> <Analytics.Provider cart={data.cart} shop={data.shop} consent={data.consent} > <Outlet /> </Analytics.Provider> </body> </html> ); }