Next.js

The SDK runs in the browser only, so Next.js gets a small client-component provider. npx sonder-init writes both files below and wires the layout for you.

1 · The provider

npm install @sonderhq/sdk
// app/sonder-provider.tsx — created for you by `npx sonder-init`
"use client";

import { SonderProvider } from "@sonderhq/sdk/next";
import type { ReactNode } from "react";

export function SonderClientProvider({ children }: { readonly children: ReactNode }) {
  return (
    <SonderProvider
      writeKey="snd_pk_your_write_key"
      buildId={process.env.NEXT_PUBLIC_SONDER_BUILD_ID ?? "next"}
    >
      {children}
    </SonderProvider>
  );
}

@sonderhq/sdk/next is the same provider as @sonderhq/sdk/react with the "use client" banner already applied, so importing it from a server component tree just works.

2 · Wrap the root layout

// app/layout.tsx
import { SonderClientProvider } from "./sonder-provider";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <SonderClientProvider>{children}</SonderClientProvider>
      </body>
    </html>
  );
}

Route changes and SSR

  • App Router navigations use the History API under the hood; the SDK instruments pushState/replaceState/popstate, so client-side navigations appear as nav events with parametrized routes.
  • On the server the client is inert: no timers, no listeners, nothing captured. Events only flow from the browser.
  • Set NEXT_PUBLIC_SONDER_BUILD_ID in your deploy pipeline (a git SHA or release tag) so confirm-the-fix can attribute sessions to deploys.

Pages Router

Works the same way: render SonderProvider (from @sonderhq/sdk/react) once in _app.tsx around your page component.