From 2e2625a6cdbf9a22e17953886ae92d9a4a340a1b Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:09:04 +0000
Subject: [PATCH 1/5] Update conversions/leads/supabase.mdx
---
conversions/leads/supabase.mdx | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/conversions/leads/supabase.mdx b/conversions/leads/supabase.mdx
index 93333106..419d4d24 100644
--- a/conversions/leads/supabase.mdx
+++ b/conversions/leads/supabase.mdx
@@ -18,9 +18,11 @@ In this guide, we will be focusing on tracking new user sign-ups for a SaaS appl
## Configure Supabase
-Next, configure Supabase to track lead conversion events in the auth callback function.
+Next, configure Supabase to track lead conversion events. The implementation depends on your authentication flow:
-Here's how it works in a nutshell:
+### For OAuth and email verification flows
+
+For OAuth providers (Google, GitHub, etc.) and email signup with verification enabled, use the `/api/auth/callback` route:
1. In the `/api/auth/callback` route, check if:
- the `dub_id` cookie is present.
@@ -28,6 +30,12 @@ Here's how it works in a nutshell:
2. If the `dub_id` cookie is present and the user is a new sign up, send a lead event to Dub using `dub.track.lead`
3. Delete the `dub_id` cookie.
+### For email signup without verification
+
+
+The `/auth/callback` route handles most authentication conditions **except** normal user signup with email when email verification is disabled. For this flow, you need to add tracking code directly to your signup page.
+
+
```typescript Next.js App Router
From d29c91f93e023dae1b92acef95af105e36e23069 Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:09:31 +0000
Subject: [PATCH 2/5] Update conversions/leads/supabase.mdx
---
conversions/leads/supabase.mdx | 191 +++++++++++++++++++++++++++++++++
1 file changed, 191 insertions(+)
diff --git a/conversions/leads/supabase.mdx b/conversions/leads/supabase.mdx
index 419d4d24..7f2da5e9 100644
--- a/conversions/leads/supabase.mdx
+++ b/conversions/leads/supabase.mdx
@@ -36,6 +36,197 @@ For OAuth providers (Google, GitHub, etc.) and email signup with verification en
The `/auth/callback` route handles most authentication conditions **except** normal user signup with email when email verification is disabled. For this flow, you need to add tracking code directly to your signup page.
+When email verification is disabled, users are immediately signed in after signup without going through the `/auth/callback` route. Add the tracking code directly to your signup form handler:
+
+
+
+```typescript Client-side signup form
+// components/signup-form.tsx
+import { useState } from 'react';
+import { createClient } from '@/lib/supabase/client';
+import { dub } from '@/lib/dub';
+
+export function SignupForm() {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [loading, setLoading] = useState(false);
+
+ const supabase = createClient();
+
+ const handleSignup = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setLoading(true);
+
+ try {
+ const { data, error } = await supabase.auth.signUp({
+ email,
+ password,
+ });
+
+ if (error) throw error;
+
+ // Track the lead conversion if signup was successful
+ if (data.user) {
+ const dubId = document.cookie
+ .split('; ')
+ .find(row => row.startsWith('dub_id='))
+ ?.split('=')[1];
+
+ if (dubId) {
+ await dub.track.lead({
+ clickId: dubId,
+ eventName: 'Sign Up',
+ customerExternalId: data.user.id,
+ customerEmail: data.user.email,
+ customerName: data.user.user_metadata?.name,
+ customerAvatar: data.user.user_metadata?.avatar_url,
+ });
+
+ // Delete the dub_id cookie
+ document.cookie = 'dub_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
+ }
+ }
+ } catch (error) {
+ console.error('Signup error:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ );
+}
+```
+
+```typescript Server action (App Router)
+// app/actions/auth.ts
+'use server';
+
+import { cookies } from 'next/headers';
+import { createClient } from '@/lib/supabase/server';
+import { dub } from '@/lib/dub';
+import { redirect } from 'next/navigation';
+
+export async function signUp(formData: FormData) {
+ const email = formData.get('email') as string;
+ const password = formData.get('password') as string;
+
+ const supabase = createClient(cookies());
+ const { data, error } = await supabase.auth.signUp({
+ email,
+ password,
+ });
+
+ if (error) {
+ throw new Error(error.message);
+ }
+
+ // Track the lead conversion if signup was successful
+ if (data.user) {
+ const dubId = cookies().get('dub_id')?.value;
+
+ if (dubId) {
+ await dub.track.lead({
+ clickId: dubId,
+ eventName: 'Sign Up',
+ customerExternalId: data.user.id,
+ customerEmail: data.user.email,
+ customerName: data.user.user_metadata?.name,
+ customerAvatar: data.user.user_metadata?.avatar_url,
+ });
+
+ // Delete the dub_id cookie
+ cookies().delete('dub_id');
+ }
+ }
+
+ redirect('/dashboard');
+}
+```
+
+```typescript API route (Pages Router)
+// pages/api/auth/signup.ts
+import { NextApiRequest, NextApiResponse } from 'next';
+import { createClient } from '@supabase/supabase-js';
+import { dub } from '@/lib/dub';
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ if (req.method !== 'POST') {
+ return res.status(405).json({ error: 'Method not allowed' });
+ }
+
+ const { email, password } = req.body;
+
+ const supabase = createClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.SUPABASE_SERVICE_ROLE_KEY!
+ );
+
+ try {
+ const { data, error } = await supabase.auth.signUp({
+ email,
+ password,
+ });
+
+ if (error) throw error;
+
+ // Track the lead conversion if signup was successful
+ if (data.user) {
+ const { dub_id } = req.cookies;
+
+ if (dub_id) {
+ await dub.track.lead({
+ clickId: dub_id,
+ eventName: 'Sign Up',
+ customerExternalId: data.user.id,
+ customerEmail: data.user.email,
+ customerName: data.user.user_metadata?.name,
+ customerAvatar: data.user.user_metadata?.avatar_url,
+ });
+
+ // Delete the dub_id cookie
+ res.setHeader(
+ 'Set-Cookie',
+ 'dub_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
+ );
+ }
+ }
+
+ res.status(200).json({ user: data.user });
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+}
+```
+
+
+
+## Auth callback implementation
+
+For OAuth and email verification flows, implement the `/auth/callback` route:
+
```typescript Next.js App Router
From adce6e8690caf714ddc0377a19ebae5d54d388d0 Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:25:58 +0000
Subject: [PATCH 3/5] Update conversions/leads/supabase.mdx
---
conversions/leads/supabase.mdx | 25 +++----------------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/conversions/leads/supabase.mdx b/conversions/leads/supabase.mdx
index 7f2da5e9..5ff87f7d 100644
--- a/conversions/leads/supabase.mdx
+++ b/conversions/leads/supabase.mdx
@@ -44,7 +44,6 @@ When email verification is disabled, users are immediately signed in after signu
// components/signup-form.tsx
import { useState } from 'react';
import { createClient } from '@/lib/supabase/client';
-import { dub } from '@/lib/dub';
export function SignupForm() {
const [email, setEmail] = useState('');
@@ -65,27 +64,9 @@ export function SignupForm() {
if (error) throw error;
- // Track the lead conversion if signup was successful
- if (data.user) {
- const dubId = document.cookie
- .split('; ')
- .find(row => row.startsWith('dub_id='))
- ?.split('=')[1];
-
- if (dubId) {
- await dub.track.lead({
- clickId: dubId,
- eventName: 'Sign Up',
- customerExternalId: data.user.id,
- customerEmail: data.user.email,
- customerName: data.user.user_metadata?.name,
- customerAvatar: data.user.user_metadata?.avatar_url,
- });
-
- // Delete the dub_id cookie
- document.cookie = 'dub_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
- }
- }
+ // For lead tracking, use one of the server-side approaches below
+ // The dub.track.lead SDK only works on the server side
+
} catch (error) {
console.error('Signup error:', error);
} finally {
From f70104794ee0fb8212651b1c66747edd073c9f9d Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:29:52 +0000
Subject: [PATCH 4/5] Update conversions/leads/supabase.mdx
---
conversions/leads/supabase.mdx | 182 +--------------------------------
1 file changed, 2 insertions(+), 180 deletions(-)
diff --git a/conversions/leads/supabase.mdx b/conversions/leads/supabase.mdx
index 5ff87f7d..e4cd7d07 100644
--- a/conversions/leads/supabase.mdx
+++ b/conversions/leads/supabase.mdx
@@ -20,9 +20,9 @@ In this guide, we will be focusing on tracking new user sign-ups for a SaaS appl
Next, configure Supabase to track lead conversion events. The implementation depends on your authentication flow:
-### For OAuth and email verification flows
+## Auth callback implementation
-For OAuth providers (Google, GitHub, etc.) and email signup with verification enabled, use the `/api/auth/callback` route:
+For OAuth providers (Google, GitHub, etc.) and email signup with verification enabled, implement the `/auth/callback` route:
1. In the `/api/auth/callback` route, check if:
- the `dub_id` cookie is present.
@@ -30,184 +30,6 @@ For OAuth providers (Google, GitHub, etc.) and email signup with verification en
2. If the `dub_id` cookie is present and the user is a new sign up, send a lead event to Dub using `dub.track.lead`
3. Delete the `dub_id` cookie.
-### For email signup without verification
-
-
-The `/auth/callback` route handles most authentication conditions **except** normal user signup with email when email verification is disabled. For this flow, you need to add tracking code directly to your signup page.
-
-
-When email verification is disabled, users are immediately signed in after signup without going through the `/auth/callback` route. Add the tracking code directly to your signup form handler:
-
-
-
-```typescript Client-side signup form
-// components/signup-form.tsx
-import { useState } from 'react';
-import { createClient } from '@/lib/supabase/client';
-
-export function SignupForm() {
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
- const [loading, setLoading] = useState(false);
-
- const supabase = createClient();
-
- const handleSignup = async (e: React.FormEvent) => {
- e.preventDefault();
- setLoading(true);
-
- try {
- const { data, error } = await supabase.auth.signUp({
- email,
- password,
- });
-
- if (error) throw error;
-
- // For lead tracking, use one of the server-side approaches below
- // The dub.track.lead SDK only works on the server side
-
- } catch (error) {
- console.error('Signup error:', error);
- } finally {
- setLoading(false);
- }
- };
-
- return (
-
- );
-}
-```
-
-```typescript Server action (App Router)
-// app/actions/auth.ts
-'use server';
-
-import { cookies } from 'next/headers';
-import { createClient } from '@/lib/supabase/server';
-import { dub } from '@/lib/dub';
-import { redirect } from 'next/navigation';
-
-export async function signUp(formData: FormData) {
- const email = formData.get('email') as string;
- const password = formData.get('password') as string;
-
- const supabase = createClient(cookies());
- const { data, error } = await supabase.auth.signUp({
- email,
- password,
- });
-
- if (error) {
- throw new Error(error.message);
- }
-
- // Track the lead conversion if signup was successful
- if (data.user) {
- const dubId = cookies().get('dub_id')?.value;
-
- if (dubId) {
- await dub.track.lead({
- clickId: dubId,
- eventName: 'Sign Up',
- customerExternalId: data.user.id,
- customerEmail: data.user.email,
- customerName: data.user.user_metadata?.name,
- customerAvatar: data.user.user_metadata?.avatar_url,
- });
-
- // Delete the dub_id cookie
- cookies().delete('dub_id');
- }
- }
-
- redirect('/dashboard');
-}
-```
-
-```typescript API route (Pages Router)
-// pages/api/auth/signup.ts
-import { NextApiRequest, NextApiResponse } from 'next';
-import { createClient } from '@supabase/supabase-js';
-import { dub } from '@/lib/dub';
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- if (req.method !== 'POST') {
- return res.status(405).json({ error: 'Method not allowed' });
- }
-
- const { email, password } = req.body;
-
- const supabase = createClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.SUPABASE_SERVICE_ROLE_KEY!
- );
-
- try {
- const { data, error } = await supabase.auth.signUp({
- email,
- password,
- });
-
- if (error) throw error;
-
- // Track the lead conversion if signup was successful
- if (data.user) {
- const { dub_id } = req.cookies;
-
- if (dub_id) {
- await dub.track.lead({
- clickId: dub_id,
- eventName: 'Sign Up',
- customerExternalId: data.user.id,
- customerEmail: data.user.email,
- customerName: data.user.user_metadata?.name,
- customerAvatar: data.user.user_metadata?.avatar_url,
- });
-
- // Delete the dub_id cookie
- res.setHeader(
- 'Set-Cookie',
- 'dub_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
- );
- }
- }
-
- res.status(200).json({ user: data.user });
- } catch (error) {
- res.status(400).json({ error: error.message });
- }
-}
-```
-
-
-
-## Auth callback implementation
-
-For OAuth and email verification flows, implement the `/auth/callback` route:
-
```typescript Next.js App Router
From 0d5a46559589fa6aa8dbacf74ed3203722ea2e13 Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 1 Oct 2025 04:30:11 +0000
Subject: [PATCH 5/5] Update conversions/leads/supabase.mdx
---
conversions/leads/supabase.mdx | 116 +++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/conversions/leads/supabase.mdx b/conversions/leads/supabase.mdx
index e4cd7d07..cc2c4d1f 100644
--- a/conversions/leads/supabase.mdx
+++ b/conversions/leads/supabase.mdx
@@ -139,6 +139,122 @@ export default async function handler(
+## Email signup without verification
+
+
+The `/auth/callback` route handles most authentication conditions **except** normal user signup with email when email verification is disabled. For this flow, you need to add tracking code directly to your signup page.
+
+
+When email verification is disabled, users are immediately signed in after signup without going through the `/auth/callback` route. Add the tracking code directly to your signup form handler:
+
+
+
+```typescript Server action (App Router)
+// app/actions/auth.ts
+'use server';
+
+import { cookies } from 'next/headers';
+import { createClient } from '@/lib/supabase/server';
+import { dub } from '@/lib/dub';
+import { redirect } from 'next/navigation';
+
+export async function signUp(formData: FormData) {
+ const email = formData.get('email') as string;
+ const password = formData.get('password') as string;
+
+ const supabase = createClient(cookies());
+ const { data, error } = await supabase.auth.signUp({
+ email,
+ password,
+ });
+
+ if (error) {
+ throw new Error(error.message);
+ }
+
+ // Track the lead conversion if signup was successful
+ if (data.user) {
+ const dubId = cookies().get('dub_id')?.value;
+
+ if (dubId) {
+ await dub.track.lead({
+ clickId: dubId,
+ eventName: 'Sign Up',
+ customerExternalId: data.user.id,
+ customerEmail: data.user.email,
+ customerName: data.user.user_metadata?.name,
+ customerAvatar: data.user.user_metadata?.avatar_url,
+ });
+
+ // Delete the dub_id cookie
+ cookies().delete('dub_id');
+ }
+ }
+
+ redirect('/dashboard');
+}
+```
+
+```typescript API route (Pages Router)
+// pages/api/auth/signup.ts
+import { NextApiRequest, NextApiResponse } from 'next';
+import { createClient } from '@supabase/supabase-js';
+import { dub } from '@/lib/dub';
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ if (req.method !== 'POST') {
+ return res.status(405).json({ error: 'Method not allowed' });
+ }
+
+ const { email, password } = req.body;
+
+ const supabase = createClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.SUPABASE_SERVICE_ROLE_KEY!
+ );
+
+ try {
+ const { data, error } = await supabase.auth.signUp({
+ email,
+ password,
+ });
+
+ if (error) throw error;
+
+ // Track the lead conversion if signup was successful
+ if (data.user) {
+ const { dub_id } = req.cookies;
+
+ if (dub_id) {
+ await dub.track.lead({
+ clickId: dub_id,
+ eventName: 'Sign Up',
+ customerExternalId: data.user.id,
+ customerEmail: data.user.email,
+ customerName: data.user.user_metadata?.name,
+ customerAvatar: data.user.user_metadata?.avatar_url,
+ });
+
+ // Delete the dub_id cookie
+ res.setHeader(
+ 'Set-Cookie',
+ 'dub_id=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
+ );
+ }
+ }
+
+ res.status(200).json({ user: data.user });
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+}
+```
+
+
+
## Example App