Next.js revenue attribution
Step-by-step guide for attributing revenue in Next.js applications.
1. Install the pixel
Add the attribu.tech tracking script to your root layout. If you've already done this, skip to step 2.
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
<Script
defer
data-website-id="YOUR_SITE_ID"
data-domain="yourdomain.com"
src="https://attribu.tech/js/script.js"
strategy="afterInteractive"
/>
</html>
);
}See the full Next.js installation guide for Pages Router setup and advanced options.
2. Connect Stripe
Go to Settings > Revenue in your attribu.tech dashboard and paste your Stripe restricted API key. This lets attribu.tech read charges and link them to visitors.
See Connect Stripe for detailed instructions on creating a restricted key.
3. Pass cookies in checkout
This is the key step. When creating a Stripe Checkout Session on the server, read the attribu.tech cookies and pass them as metadata:
// app/api/checkout/route.ts
import { cookies } from "next/headers";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const { priceId } = await req.json();
const cookieStore = await cookies();
const session = await stripe.checkout.sessions.create({
mode: "payment", // or "subscription"
line_items: [{ price: priceId, quantity: 1 }],
success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
metadata: {
attribu_visitor_id: cookieStore.get("attribu_visitor_id")?.value || "",
attribu_session_id: cookieStore.get("attribu_session_id")?.value || "",
},
});
return Response.json({ url: session.url });
}metadata field must be on the Checkout Session itself, not on the line item or product. attribu.tech reads session-level metadata from the Stripe webhook.4. Next.js 15+ note
In Next.js 15 and later, cookies() is asynchronous and must be awaited. The example above already uses await cookies(). If you're on Next.js 14, you can remove the await:
// Next.js 14 (synchronous cookies)
const cookieStore = cookies();What's next
- Revenue attribution overview - How first-touch attribution works.
- Email-based attribution - Fallback for when cookies can't be passed.
- Custom events - Track signups, clicks, and other actions.