Skip to main content
For React Router in framework mode (the successor of Remix), rendered on the server. Tested by the example examples/react-router-ssr (React Router 8.4.0 with ssr: true, served by @react-router/serve), which runs in the browser test matrix.

Where the tag goes

Render the tag as a <script> element in the <head> of the root layout, app/root.tsx. React writes it into the server-rendered HTML; on the client, React does not run it a second time. In the example, the values come from the server’s environment so tests can use their own site id:
The root loader reads them from the release manifest of the tracker package:
In your app, write the three values from the console’s tag directly into the element instead: src, integrity and data-website-id of
Write crossOrigin in JSX; React renders it as crossorigin.

Route changes

The first load is server rendered and is one pageview. Later navigations happen on the client with history.pushState, which the tracker watches, so each is one pageview; back and forward too.

Custom events

Declare window.umami once and call it with optional chaining, as in the Vite and React guide; the example’s app/routes/home.tsx does exactly that.

What the browser tests check

One pageview per server-rendered load and per client-side navigation, back and forward, the previous route as referrer, an external referrer on the first pageview, the tag rendered with the release’s integrity value, both kinds of custom event, Global Privacy Control and a tampered tracker refused (tests/e2e/specs, examples/react-router-ssr/test).