Skip to main content
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

Configure Clerk to track lead conversion events when users sign up.
1

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
2

Add Custom Claim to Session Token

In Clerk dashboard, add this custom claim:
{
  "metadata": "{{user.public_metadata}}"
}
3

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 />;
}
4

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

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

Track leads in your Next-Auth callback configuration.Use the signIn callback to track leads when users authenticate.

Appwrite

Configure Appwrite to track lead conversions during signup.
1

Install Dependencies

npm install node-appwrite @dub/analytics
2

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>
3

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,
  });
}
4

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

Track lead conversions with Better Auth in your Next.js app.

Analytics & Tag Managers

Google Tag Manager

1

Create Analytics Tag

  1. Navigate to GTM workspace
  2. Click Tags > New
  3. Select Custom HTML tag type
2

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>
3

Configure Trigger

  • Set trigger to “All Pages”
  • Tag will fire on every page load
4

Save and Publish

  • Name tag “Dub Analytics”
  • Save changes
  • Submit and publish to activate
Create a variable to read the dub_id cookie:
1

Create Cookie Variable

  • Go to Variables > New
  • Variable Type: 1st Party Cookie
  • Cookie Name: dub_id
  • Name: “Dub ID Cookie”
2

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>
3

Set Page View Trigger

Fire on pages matching:
  • Page URL contains /order-confirmation
  • Or Page Path equals /checkout/success

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

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:
  1. User is tracked as a lead with customerExternalId
  2. Stripe checkout includes same ID in metadata
  3. Dub receives Stripe webhook when payment succeeds
  4. Sale is attributed to original click via customer ID

Stripe Customer Objects

Link Stripe customer objects to Dub customers for automatic sale attribution.

E-commerce Platforms

Shopify

1

Install Shopify App

Install the Dub Shopify App from the Shopify App Store.
2

Activate Analytics Script

  1. Go to Shopify Admin > Online Store > Themes
  2. Click Customize on your active theme
  3. Select App embeds tab
  4. Find “Dub Analytics Script”
  5. Toggle to activate
3

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 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

1

Install Package

npm install @dub/analytics
2

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

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"
  }'

Server-Side SDKs

Dub provides SDKs for multiple languages:
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',
});

Best Practices

  • 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
Always test integrations in development:
  1. Use test API keys
  2. Verify cookie setting
  3. Confirm events appear in dashboard
  4. Test end-to-end attribution flow
  • Check conversion rates regularly
  • Set up alerts for attribution drops
  • Verify webhook delivery (for payment processors)
  • Test after deploying changes
Use the same customerExternalId across:
  • Lead tracking
  • Sale tracking
  • Payment processor metadata
This ensures proper attribution throughout the funnel.

Build docs developers (and LLMs) love