Integrate Dub with your existing tech stack to automatically track conversions across your platform. These guides cover authentication providers, analytics platforms, payment processors, and more.
Authentication Providers
Track user signups as lead conversions by integrating with your authentication provider.
Clerk
Integrate Dub with Clerk authentication
Configure Clerk to track lead conversion events when users sign up.
Add Environment Variables
# Get from https://dashboard.clerk.com/apps/new
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY = your_publishable_key
CLERK_SECRET_KEY = your_secret_key
# Get from https://d.to/tokens
DUB_API_KEY = your_api_key
Add Custom Claim to Session Token
In Clerk dashboard, add this custom claim: {
"metadata" : "{{user.public_metadata}}"
}
Create DubAnalytics Component
"use client" ;
import { trackLead } from "@/actions/track-lead" ;
import { useUser } from "@clerk/nextjs" ;
import { Analytics } from "@dub/analytics/react" ;
import { useEffect } from "react" ;
export function DubAnalytics () {
const { user } = useUser ();
useEffect (() => {
if ( ! user || user . publicMetadata . dubClickId ) return ;
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 );
});
}, [ user ]);
return < Analytics />;
}
Implement trackLead 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 }) {
try {
const cookieStore = await cookies ();
const dubId = cookieStore . get ( "dub_id" )?. value ;
if ( dubId ) {
await dub . track . lead ({
clickId: dubId ,
eventName: "Sign Up" ,
customerExternalId: id ,
customerName: name ,
customerEmail: email ,
customerAvatar: avatar ,
});
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 ) {
return { ok: false , error: error . message };
}
}
Supabase
Integrate Dub with Supabase Auth
Track leads in the Supabase auth callback function. // app/api/auth/callback/route.ts
import { dub } from "@/lib/dub" ;
import { createClient } from "@/lib/supabase/server" ;
import { cookies } from "next/headers" ;
import { NextResponse } from "next/server" ;
export async function GET ( request : Request ) {
const { searchParams , origin } = new URL ( request . url );
const code = searchParams . get ( "code" );
const next = searchParams . get ( "next" ) ?? "/" ;
if ( code ) {
const supabase = createClient ( cookies ());
const { data , error } = await supabase . auth . exchangeCodeForSession ( code );
if ( ! error ) {
const { user } = data ;
const dub_id = cookies (). get ( "dub_id" )?. value ;
// User created in last 10 minutes is considered new
const isNewUser =
new Date ( user . created_at ) > new Date ( Date . now () - 10 * 60 * 1000 );
if ( dub_id && isNewUser ) {
await dub . track . lead ({
clickId: dub_id ,
eventName: "Sign Up" ,
customerExternalId: user . id ,
customerName: user . user_metadata . name ,
customerEmail: user . email ,
customerAvatar: user . user_metadata . avatar_url ,
});
cookies (). delete ( "dub_id" );
}
return NextResponse . redirect ( ` ${ origin }${ next } ` );
}
}
return NextResponse . redirect ( ` ${ origin } /auth/auth-code-error` );
}
Auth0
Track lead events after Auth0 authentication completes. Similar to other auth providers, read the dub_id cookie in your Auth0 callback and track the lead event server-side.
Next-Auth
Integrate Dub with Next-Auth
Track leads in your Next-Auth callback configuration. Use the signIn callback to track leads when users authenticate.
Appwrite
Integrate Dub with Appwrite
Configure Appwrite to track lead conversions during signup.
Install Dependencies
npm install node-appwrite @dub/analytics
Set Environment Variables
NEXT_PUBLIC_APPWRITE_ENDPOINT = https://cloud.appwrite.io/v1
NEXT_PUBLIC_APPWRITE_PROJECT =< APPWRITE_PROJECT_ID >
NEXT_APPWRITE_KEY =< APPWRITE_API_KEY >
NEXT_DUB_API_KEY =< DUB_API_KEY >
Create Dub Lead Tracking Function
import { Dub } from "dub" ;
import type { Models } from "node-appwrite" ;
const dub = new Dub ({
token: process . env . NEXT_DUB_API_KEY ,
});
export function addDubLead (
user : Models . User < Models . Preferences >,
dub_id : string ,
) {
dub . track . lead ({
clickId: dub_id ,
eventName: "Sign Up" ,
customerExternalId: user . $id ,
customerName: user . name ,
customerEmail: user . email ,
});
}
Track Leads on Signup
import { addDubLead } from "@/lib/server/dub" ;
import { cookies } from "next/headers" ;
async function signUpWithEmail ( formData : FormData ) {
"use server" ;
const email = formData . get ( "email" );
const password = formData . get ( "password" );
const name = formData . get ( "name" );
const { account } = await createAdminClient ();
const user = await account . create ( ID . unique (), email , password , name );
const session = await account . createEmailPasswordSession ( email , password );
( await cookies ()). set ( "my-custom-session" , session . secret , {
path: "/" ,
httpOnly: true ,
sameSite: "strict" ,
secure: true ,
});
// Track lead if dub_id exists
const dub_id = ( await cookies ()). get ( "dub_id" )?. value ;
if ( dub_id ) {
addDubLead ( user , dub_id );
( await cookies ()). delete ( "dub_id" );
}
redirect ( "/auth/success" );
}
Better Auth
Integrate Dub with Better Auth
Track lead conversions with Better Auth in your Next.js app.
Analytics & Tag Managers
Google Tag Manager
Install Dub Analytics via Google Tag Manager
Create Analytics Tag
Navigate to GTM workspace
Click Tags > New
Select Custom HTML tag type
Add Dub Script
< script >
( function ( c , n ) {
c [ n ] =
c [ n ] ||
function () {
( c [ n ]. q = c [ n ]. q || []). push ( arguments );
};
var methods = [ "trackClick" , "trackLead" , "trackSale" ];
for ( var i = 0 ; i < methods . length ; i ++ ) {
( function ( method ) {
c [ n ][ method ] = function () {
var args = Array . prototype . slice . call ( arguments );
args . unshift ( method );
c [ n ]. apply ( null , args );
};
})( methods [ i ]);
}
var s = document . createElement ( "script" );
s . defer = 1 ;
s . src = "https://www.dubcdn.com/analytics/script.js" ;
document . head . appendChild ( s );
})( window , "dubAnalytics" );
</ script >
Configure Trigger
Set trigger to “All Pages”
Tag will fire on every page load
Save and Publish
Name tag “Dub Analytics”
Save changes
Submit and publish to activate
Create a variable to read the dub_id cookie:
Create Cookie Variable
Go to Variables > New
Variable Type: 1st Party Cookie
Cookie Name: dub_id
Name: “Dub ID Cookie”
Create Sale Tracking Tag
For order confirmation page: < script >
( function () {
var params = new URLSearchParams ( window . location . search );
var customerId = params . get ( "customer_id" );
var amount = params . get ( "amount" );
var invoiceId = params . get ( "invoice_id" );
var clickId = {{ Dub ID Cookie }} || "" ;
if ( customerId && amount && clickId ) {
dubAnalytics . trackSale ({
eventName: "Purchase" ,
customerExternalId: customerId ,
amount: parseInt ( amount ),
invoiceId: invoiceId || undefined ,
currency: "usd" ,
paymentProcessor: "stripe" ,
clickId: clickId ,
});
}
})();
</ script >
Set Page View Trigger
Fire on pages matching:
Page URL contains /order-confirmation
Or Page Path equals /checkout/success
Segment
Track conversions via Segment
Forward Segment events to Dub for conversion tracking. Use Segment’s HTTP API destination to send lead and sale events to Dub’s tracking endpoints.
Payment Processors
Stripe Checkout
Track Stripe Checkout conversions
Associate Stripe customers with Dub attribution by passing the customer ID in checkout metadata. import { stripe } from "@/lib/stripe" ;
const session = await stripe . checkout . sessions . create ({
customer_email: user . email ,
success_url: "https://app.example.com/success" ,
line_items: [{ price: priceId , quantity: 1 }],
mode: "subscription" ,
client_reference_id: user . teamId ,
metadata: {
dubCustomerExternalId: user . id , // Your internal user ID
},
});
Dub listens for Stripe webhook events and automatically tracks sales when checkout completes.
How it works:
User is tracked as a lead with customerExternalId
Stripe checkout includes same ID in metadata
Dub receives Stripe webhook when payment succeeds
Sale is attributed to original click via customer ID
Stripe Payment Links
Use Stripe Payment Links with Dub
Similar to Checkout, configure Payment Links to include customer metadata for attribution.
Stripe Customer Objects
Associate Stripe Customers
Link Stripe customer objects to Dub customers for automatic sale attribution.
Shopify
Activate Analytics Script
Go to Shopify Admin > Online Store > Themes
Click Customize on your active theme
Select App embeds tab
Find “Dub Analytics Script”
Toggle to activate
Verify Installation
Visit your store
Check browser console for Dub analytics script
Test a purchase to verify tracking
Sales are automatically tracked when customers complete checkout. No additional code required.
Webflow
Add Dub Analytics to Webflow
Add the Dub analytics script to your Webflow site’s custom code section.
WordPress
Add the Dub analytics script via a custom HTML block or theme footer.
Framer
Use Framer’s custom code feature to add the Dub analytics script to all pages.
SDK & Manual Integration
React
Install Package
npm install @dub/analytics
Add Analytics Component
import { Analytics } from '@dub/analytics/react' ;
export default function RootLayout ({ children }) {
return (
< html lang = "en" >
< body > { children } </ body >
< Analytics />
</ html >
);
}
REST API
Track conversions via REST API
curl -X POST https://api.dub.co/track/lead \
-H "Authorization: Bearer dub_xxxxxx" \
-H "Content-Type: application/json" \
-d '{
"clickId": "rLnWe1uz9t282v7g",
"eventName": "Sign Up",
"customerExternalId": "user_123",
"customerName": "John Doe",
"customerEmail": "john@example.com"
}'
curl -X POST https://api.dub.co/track/sale \
-H "Authorization: Bearer dub_xxxxxx" \
-H "Content-Type: application/json" \
-d '{
"customerExternalId": "user_123",
"amount": 5000,
"currency": "usd",
"paymentProcessor": "stripe",
"eventName": "Purchase"
}'
Server-Side SDKs
Dub provides SDKs for multiple languages: TypeScript
Python
PHP
Ruby
Go
import { Dub } from 'dub' ;
const dub = new Dub ({
token: process . env . DUB_API_KEY ,
});
await dub . track . lead ({
clickId: 'rLnWe1uz9t282v7g' ,
eventName: 'Sign Up' ,
customerExternalId: 'user_123' ,
});
from dub import Dub
dub = Dub( token = os.environ[ 'DUB_API_KEY' ])
dub.track.lead(
click_id = 'rLnWe1uz9t282v7g' ,
event_name = 'Sign Up' ,
customer_external_id = 'user_123'
)
use Dub\ Dub ;
$dub = new Dub ([
'token' => getenv ( 'DUB_API_KEY' )
]);
$dub -> track -> lead ([
'clickId' => 'rLnWe1uz9t282v7g' ,
'eventName' => 'Sign Up' ,
'customerExternalId' => 'user_123'
]);
require 'dub'
dub = Dub :: Client . new ( token: ENV [ 'DUB_API_KEY' ])
dub. track . lead (
click_id: 'rLnWe1uz9t282v7g' ,
event_name: 'Sign Up' ,
customer_external_id: 'user_123'
)
import " github.com/dubinc/dub-go "
client := dub . New ( dub . WithToken ( os . Getenv ( "DUB_API_KEY" )))
client . Track . Lead ( context . Background (), & dub . TrackLeadRequest {
ClickID : "rLnWe1uz9t282v7g" ,
EventName : "Sign Up" ,
CustomerExternalID : "user_123" ,
})
Best Practices
Choose the Right Integration Method
Authentication providers : Track leads at signup
Payment processors : Automatic sale attribution via metadata
E-commerce platforms : Use official apps when available
Custom apps : Use SDKs for type safety and better DX
Test in Development First
Always test integrations in development:
Use test API keys
Verify cookie setting
Confirm events appear in dashboard
Test end-to-end attribution flow
Monitor Integration Health
Check conversion rates regularly
Set up alerts for attribution drops
Verify webhook delivery (for payment processors)
Test after deploying changes
Keep Customer IDs Consistent
Use the same customerExternalId across:
Lead tracking
Sale tracking
Payment processor metadata
This ensures proper attribution throughout the funnel.