Next.js
-
Install the package.
Terminal window npm install @ritim/browser-sdk -
Create a client component.
init()toucheswindow, so it cannot run during server rendering —'use client'and an effect are both required.app/ritim.tsx 'use client';import { useEffect } from 'react';import { init } from '@ritim/browser-sdk';export function Ritim() {useEffect(() => {init({ projectKey: 'P-ABC123' });}, []);return null;} -
Render it once, in the root layout.
app/layout.tsx import { Ritim } from './ritim';export default function RootLayout({ children }: { children: React.ReactNode }) {return (<html lang="en"><body>{children}<Ritim /></body></html>);}
That is the whole integration. You do not wire anything into useRouter,
usePathname or useSearchParams — the App Router navigates by calling
history.pushState, which the SDK already watches.
Pages Router
Section titled “Pages Router”The same component works; render it in _app.tsx instead:
import type { AppProps } from 'next/app';import { Ritim } from '../components/ritim';
export default function App({ Component, pageProps }: AppProps) { return ( <> <Component {...pageProps} /> <Ritim /> </> );}Use next/script so Next controls when it loads, and put it in the root layout:
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> {children} <Script src="https://cdn.ritim.io/latest/rum.min.js" strategy="afterInteractive" data-project-key="P-ABC123" /> </body> </html> );}afterInteractive is the right strategy: the SDK must not block hydration, and
beforeInteractive would do exactly that for no benefit — it recovers earlier
metrics from buffered entries either way.
On the Pages Router, the same <Script> goes in pages/_app.tsx.
Navigation still needs no wiring — the App Router calls history.pushState,
which the SDK watches on its own.
Releases
Section titled “Releases”The SDK recognises Next.js and reads the build identifier Next publishes on the page. What it finds depends on your setup — and one line of config makes it reliable everywhere:
| Setup | Release detected? |
|---|---|
deploymentId set, either router |
Yes — and it is the value you chose |
| Pages Router, nothing configured | Yes — Next’s own build id |
| App Router on Vercel | Usually — from the platform’s deployment id |
| App Router self-hosted, nothing set | No — falls back to the asset fingerprint |
The App Router does not expose the build id the Pages Router does, so on a self-hosted App Router app there is nothing for the SDK to read and measurements fall through to the asset fingerprint. That still tells you the version changed; it cannot tell you which version it is.
Set a deploymentId
Section titled “Set a deploymentId”This is the one to reach for. Next has a config option whose entire job is to
name a deployment, and the SDK reads it automatically — on both routers,
self-hosted or not, and on both install paths. Nothing to pass to init(),
nothing to add to the script tag:
import type { NextConfig } from 'next';
const nextConfig: NextConfig = { deploymentId: process.env.GIT_SHA,};
export default nextConfig;Set it once and every measurement carries a release you can look up in your own history.
If you want the label without the skew protection,
generateBuildId
sets the Pages Router build id and does nothing else:
const nextConfig: NextConfig = { generateBuildId: () => process.env.GIT_SHA ?? null,};Returning null keeps Next’s default. This only helps the Pages Router — the
App Router has no build id for the SDK to read, so there deploymentId is the
only config-level option.
Or declare it in code
Section titled “Or declare it in code”When neither config option fits, hand the value to the SDK yourself:
init({ projectKey: 'P-ABC123', release: process.env.NEXT_PUBLIC_BUILD_ID,});NEXT_PUBLIC_ is the prefix Next requires for a variable to reach the browser —
see Environment
variables.
<Script src="https://cdn.ritim.io/latest/rum.min.js" strategy="afterInteractive" data-project-key="P-ABC123" data-release={process.env.NEXT_PUBLIC_BUILD_ID}/>NEXT_PUBLIC_ is the prefix Next requires for a variable to reach the browser —
see Environment
variables.