OnyxMetric
Integration GuidesReact

Remix

Add OnyxMetric analytics to your Remix app

Remix renders the full HTML document from app/root.tsx, so a tag in that file's <head> reaches every route.

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 Remix

Open app/root.tsx (or root.jsx) and add the tag inside <head>, after <Meta /> and <Links />:

app/root.tsx
export default function App() {
  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></script>
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

Restart the dev server after the change. Client-side navigation following the first server render 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

Remix renders components on the server, so check for window first.

app/routes/offer.tsx
export default function OfferRoute() {
  const handleClick = () => {
    if (typeof window !== "undefined") {
      (window as any).onyx?.event("offer_claimed", { feature: "Special offer" });
    }
  };

  return <button onClick={handleClick}>Claim offer</button>;
}

Troubleshooting

  • Missing pageviews after client navigation: rare. If it happens, call window.onyx.pageview() from a root-level effect that depends on useLocation(), after testing the default.

Next steps

On this page