Skip to Content
Developer DocsConversion trackingLeadsClerk

// snippet import removed // snippet import removed // snippet import removed // snippet import removed

In this guide, we will be focusing on tracking new user sign-ups for a SaaS application that uses Clerk for user authentication.

Configure Clerk

Next, configure Clerk to track lead conversion events when a new user signs up. Here’s a quick video showing how to do this:

Here’s a quick summary of the steps:

Add environment variables

Add the following environment variables to your app:

# get it here: https://dashboard.clerk.com/apps/new NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_publishable_key CLERK_SECRET_KEY=your_secret_key # get it here: https://d.to/tokens DUB_API_KEY=your_api_key

Add a custom claim to your Clerk session token

Add the following JSON as a custom claim  to your Clerk session token:

{ "metadata": "{{user.public_metadata}}" }

Extend the `@dub/analytics` package with Clerk's `useUser` hook

Extend the @dub/analytics package to include a trackLead server action.

"use client"; import { trackLead } from "@/actions/track-lead"; import { useUser } from "@clerk/nextjs"; import { Analytics, AnalyticsProps } from "@dub/analytics/react"; import { useEffect } from "react"; export function DubAnalytics(props: AnalyticsProps) { const { user } = useUser(); useEffect(() => { if (!user || user.publicMetadata.dubClickId) return; // if the user is loaded but hasn't been persisted to Dub yet, track the lead event trackLead({ id: user.id, name: user.fullName!, email: user.primaryEmailAddress?.emailAddress, avatar: user.imageUrl, }).then(async (res) => { if (res.ok) await user.reload(); else console.error(res.error); }); // you can also use an API route instead of a server action /* fetch("/api/track-lead", { method: "POST", body: JSON.stringify({ id: user.id, name: user.fullName, email: user.primaryEmailAddress?.emailAddress, avatar: user.imageUrl, }), }).then(res => { if (res.ok) await user.reload(); else console.error(res.statusText); }); */ }, [user]); return <Analytics {...props} />; }

Then, add the DubAnalytics component to your app’s root layout component:

import { DubAnalytics } from "@/components/dub-analytics"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html> <body> <DubAnalytics /> {children} </body> </html> ); }

Implement the `trackLead` server action

On the server side, implement the trackLead server action. Alternatively, you can also create an API route instead:

// This is a server action "use server"; import { dub } from "@/lib/dub"; import { clerkClient } from "@clerk/nextjs/server"; import { cookies } from "next/headers"; export async function trackLead({ id, name, email, avatar, }: { id: string; name?: string | null; email?: string | null; avatar?: string | null; }) { try { const cookieStore = await cookies(); const dubId = cookieStore.get("dub_id")?.value; if (dubId) { // Send lead event to Dub await dub.track.lead({ clickId: dubId, eventName: "Sign Up", customerExternalId: id, customerName: name, customerEmail: email, customerAvatar: avatar, }); // Delete the dub_id cookie cookieStore.set("dub_id", "", { expires: new Date(0), }); } const clerk = await clerkClient(); await clerk.users.updateUser(id, { publicMetadata: { dubClickId: dubId || "n/a", }, }); return { ok: true }; } catch (error) { console.error("Error in trackLead:", error); return { ok: false, error: (error as Error).message }; } }

Example App

To learn more about how to track leads with Clerk, check out the following example app:

github

Dub + Clerk Example App

See how to track new user sign-ups with Clerk and the Dub SDK.