Skip to content

Next.js SDK

Last updated

@whisperr/next adds Whisperr to a Next.js App Router app. It re-exports WhisperrProvider and useWhisperr() from @whisperr/react behind a "use client" boundary, so you can put the provider in a server component layout. All behavior comes from @whisperr/web.

npm i @whisperr/next @whisperr/web

The packages are @whisperr/next and @whisperr/web on npm. They release together; the current version is 0.4.0.

app/layout.tsx
import { WhisperrProvider } from "@whisperr/next";
const key = process.env.NEXT_PUBLIC_WHISPERR_KEY;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{/* Without a key (a preview or CI build), the SDK stays off instead of throwing. */}
<WhisperrProvider options={{ apiKey: key ?? "", disabled: !key }}>
{children}
</WhisperrProvider>
</body>
</html>
);
}
.env.local
NEXT_PUBLIC_WHISPERR_KEY=wpk_your_publishable_key

A NEXT_PUBLIC_ variable ships in the browser bundle, so it must hold the publishable key (wpk_…), shown as an App key in Settings → API keys. Never put the server key (wrk_…) in a NEXT_PUBLIC_ variable.

app/documents/share-button.tsx
"use client";
import { useWhisperr } from "@whisperr/next";
export function ShareButton({ share }: { share: () => Promise<void> }) {
const whisperr = useWhisperr();
// Track after the action succeeds. "document_shared" is an example name.
async function onClick() {
await share();
whisperr.track("document_shared");
}
return <button onClick={onClick}>Share</button>;
}

useWhisperr() returns the full Web SDK client: identify(), track(), setAppLanguage(), reset() and the rest. See Web SDK methods. Call identify() in a client component after sign-in and when you restore a session.

How do I pass an onError callback in Next.js?

Section titled “How do I pass an onError callback in Next.js?”

A server component cannot pass a function to a client component. To use onError, or any option you build in code, wrap the provider in your own client component:

app/whisperr-provider.tsx
"use client";
import { WhisperrProvider } from "@whisperr/next";
export function AppWhisperrProvider({ children }: { children: React.ReactNode }) {
return (
<WhisperrProvider
options={{
apiKey: process.env.NEXT_PUBLIC_WHISPERR_KEY!,
onError: (error) => console.warn("whisperr", error.type, error.message),
}}
>
{children}
</WhisperrProvider>
);
}

Then render <AppWhisperrProvider> in app/layout.tsx.

For route handlers, server actions and webhooks, use @whisperr/node with the server key. Pass the same user id you pass to identify() in the browser, and both sources land on one timeline.

Common questions

Do I need to track Next.js route changes myself?

No. The Web SDK captures page_viewed on load and on every History API navigation, which covers Next.js client-side navigation.

Can I call useWhisperr() in a server component?

No. useWhisperr() is a React hook, so call it in a client component. For server-side events, use @whisperr/node with the server key.

Why must the Next.js key be a publishable key?

A NEXT_PUBLIC_ variable is built into the browser bundle, where anyone can read it. The publishable key (wpk_…) is made for that. The server key (wrk_…) must stay on your server.