SDK
Next.js App Router
TrackerProviderNext, Suspense boundaries, middleware, and server events.
Next.js App Router splits Server and Client Components. Trackrift belongs in a client provider mounted from your root layout. Automatic page_view tracks pathname changes; search params require Suspense.
'use client';
import { TrackerProviderNext } from '@trackrift/sdk/next';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<TrackerProviderNext
endpoint="https://api.trackrift.com"
publicId="YOUR_PUBLIC_ID"
autocapture={{ scrollDepth: true, clicks: true, forms: true }}
>
{children}
</TrackerProviderNext>
);
}import { Suspense } from 'react';
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Suspense fallback={null}>
<Providers>{children}</Providers>
</Suspense>
</body>
</html>
);
}TrackerProviderNext options
| autocapture key | Default | Description |
|---|---|---|
| scrollDepth | true | 25/50/75/100% milestones |
| clicks | true | Delegated click capture |
| forms | true | form_start, submit, errors |
| visibility | false | Tab focus events — noisy if enabled |
| engagementTime | true | Active time every 15s |
Server Components vs client
Do not import tracker in Server Components. For Stripe webhooks or CRM updates, use sendServerEvent in Route Handlers or Server Actions.
import { sendServerEvent } from '@trackrift/sdk/server';
export async function POST(req: Request) {
// … verify Stripe signature …
await sendServerEvent({
endpoint: process.env.TRACKRIFT_COLLECTOR_URL!,
token: process.env.SERVER_INGEST_TOKEN!,
event: {
event_name: 'purchase',
email: customer.email,
value: amount / 100,
currency: 'USD',
source: 'server',
properties: { stripe_invoice_id: invoice.id },
},
});
return new Response('ok');
}Suspense boundary
PageViewTracker uses useSearchParams — wrap the provider segment in <Suspense> if Next.js warns during static generation.