OnyxMetric
Integration Guides

Shopify Hydrogen

Add OnyxMetric analytics to your Shopify Hydrogen storefront

Hydrogen renders the HTML document from app/root.tsx. Put the tag in the <head> of that file's Layout component, and add the tracker's host to the Content Security Policy built in app/entry.server.tsx.

Copy your tracking snippet

In OnyxMetric, open your site's Site Settings and copy the tracking script. It looks like this:

<script src="https://app.onyxmetric.com/api/script.js?siteId=YOUR_SITE_ID" async></script>

YOUR_SITE_ID is the numeric ID of your site.

Add the snippet to Shopify Hydrogen

Hydrogen ships with a nonce-based CSP, so a plain <script> tag without the nonce is blocked. Use Hydrogen's Script component, which adds the nonce for you.

  1. Open app/root.tsx and add the tag inside <head> of the Layout component:
app/root.tsx
import {Script, useNonce} from '@shopify/hydrogen';

export function Layout({children}: {children?: React.ReactNode}) {
  const nonce = useNonce();

  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <Meta />
        <Links />
        <Script src="https://app.onyxmetric.com/api/script.js?siteId=YOUR_SITE_ID" async />
      </head>
      <body>
        {children}
        <ScrollRestoration nonce={nonce} />
        <Scripts nonce={nonce} />
      </body>
    </html>
  );
}
  1. Open app/entry.server.tsx and allow the tracker's host in the CSP. Values for connectSrc merge with Hydrogen's defaults. scriptSrc has no default to merge with (it falls back to default-src), so list Shopify's CDN too:
app/entry.server.tsx
const {nonce, header, NonceProvider} = createContentSecurityPolicy({
  shop: {
    checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
    storeDomain: context.env.PUBLIC_STORE_DOMAIN,
  },
  scriptSrc: ["'self'", "https://cdn.shopify.com", "https://app.onyxmetric.com"],
  connectSrc: ["https://app.onyxmetric.com"],
});

connect-src lets the tracker post events. script-src is needed because features such as session replay load a second script from the same host at runtime.

Restart the dev server for the CSP change to apply. Navigation between routes is tracked automatically.

Check that it works

Load your live site and click through a few pages. Pageviews show up in the OnyxMetric dashboard within seconds.

If nothing arrives:

  • View the page source and search for script.js?siteId= to confirm the tag is present.
  • In the browser's Network tab, check that script.js returns 200 and that requests go to /api/track.
  • Turn off ad blockers, or proxy the script through your own domain.
  • Read script troubleshooting for other causes.

Track custom events

Hydrogen's Analytics.Provider already publishes storefront events (product_viewed, product_added_to_cart, cart_updated, and others). Subscribe to them once in a small component instead of instrumenting each route.

app/components/OnyxAnalytics.tsx
import {useEffect} from 'react';
import {useAnalytics} from '@shopify/hydrogen';

export function OnyxAnalytics() {
  const {subscribe, register} = useAnalytics();
  const {ready} = register('OnyxMetric');

  useEffect(() => {
    subscribe('product_viewed', (data) => {
      const product = data.products[0];
      if (!product) return;
      window.onyx?.event('view_item', {
        item_id: product.sku || product.variantId,
        item_name: product.title,
        item_variant: product.variantTitle,
        price: Number(product.price),
      });
    });
    subscribe('product_added_to_cart', (data) => {
      const line = data.currentLine;
      if (!line) return;
      window.onyx?.event('add_to_cart', {
        item_id: line.merchandise.sku || line.merchandise.id,
        item_name: line.merchandise.product.title,
        price: Number(line.cost.totalAmount.amount),
        currency: line.cost.totalAmount.currencyCode,
        quantity: line.quantity,
      });
    });
    ready();
  }, []);

  return null;
}

Render <OnyxAnalytics /> inside <Analytics.Provider> in the App component of app/root.tsx. Declare window.onyx with the type from Track events so TypeScript accepts the calls.

Checkout does not run in Hydrogen. Track purchases with the custom web pixel from the Shopify guide, which works for Hydrogen and Online Store checkouts alike.

Troubleshooting

  • Refused to load the script in the console: the CSP change in entry.server.tsx is missing, or the dev server was not restarted.
  • POST /api/track blocked: connectSrc does not include https://app.onyxmetric.com.
  • Early events dropped: on a cold load, a subscription can fire before the script runs. The optional chaining above skips those. Wrap calls in window.onyx.onReady() if you need every one.

Next steps

On this page