Skip to main content
RapidDev - Software Development Agency
supabase-tutorial

How to Connect Supabase to Segment

Connect Supabase to Segment by sending analytics events from your application using the Segment Analytics.js SDK on the client side, and by forwarding server-side events from Supabase Edge Functions using the Segment HTTP Tracking API. Track auth events by listening to onAuthStateChange and sending identify and track calls to Segment. For database-level events, use a database webhook that triggers an Edge Function to forward the event payload to Segment.

What you'll learn

  • How to send Supabase auth events to Segment from the client
  • How to forward server-side database events to Segment via Edge Functions
  • How to use Segment identify calls to link Supabase user IDs to Segment profiles
  • How to set up a database webhook for automated event forwarding
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner7 min read15-20 minSupabase (all plans), Segment (all plans), @supabase/supabase-js v2+March 2026RapidDev Engineering Team
TL;DR

Connect Supabase to Segment by sending analytics events from your application using the Segment Analytics.js SDK on the client side, and by forwarding server-side events from Supabase Edge Functions using the Segment HTTP Tracking API. Track auth events by listening to onAuthStateChange and sending identify and track calls to Segment. For database-level events, use a database webhook that triggers an Edge Function to forward the event payload to Segment.

Sending Supabase Auth and Database Events to Segment for Analytics

Segment is a customer data platform that collects events from your application and routes them to analytics tools like Mixpanel, Amplitude, Google Analytics, and data warehouses. This tutorial shows you how to connect Supabase to Segment using two approaches: client-side tracking with Analytics.js for auth events, and server-side tracking with Edge Functions for database events. By combining both, you get complete visibility into user behavior.

Prerequisites

  • A Supabase project with authentication configured
  • A Segment workspace with a source created (get your Write Key)
  • @supabase/supabase-js v2 installed in your project
  • Basic understanding of Segment's track and identify calls

Step-by-step guide

1

Install the Segment Analytics.js SDK in your frontend

Add the Segment Analytics.js snippet or npm package to your frontend application. The Analytics.js SDK provides track, identify, and page methods for sending events to Segment. Use the npm package for framework-based apps (React, Next.js, Vue) and the snippet for plain HTML sites. Your Segment Write Key is found in the Segment Dashboard under Sources.

typescript
1// Install via npm
2// npm install @segment/analytics-next
3
4import { AnalyticsBrowser } from '@segment/analytics-next'
5
6export const analytics = AnalyticsBrowser.load({
7 writeKey: process.env.NEXT_PUBLIC_SEGMENT_WRITE_KEY!
8})

Expected result: The Segment SDK is initialized and ready to send events from the browser to your Segment source.

2

Track Supabase auth events with onAuthStateChange

Listen to Supabase auth state changes and send corresponding Segment events. When a user signs in, call analytics.identify to associate their Supabase user ID with their Segment profile, then call analytics.track to record the sign-in event. When they sign out, track the sign-out event. This creates a complete auth funnel in Segment.

typescript
1import { createClient } from '@supabase/supabase-js'
2import { analytics } from './segment'
3
4const supabase = createClient(
5 process.env.NEXT_PUBLIC_SUPABASE_URL!,
6 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
7)
8
9supabase.auth.onAuthStateChange(async (event, session) => {
10 if (event === 'SIGNED_IN' && session?.user) {
11 // Link Supabase user ID to Segment profile
12 analytics.identify(session.user.id, {
13 email: session.user.email,
14 provider: session.user.app_metadata?.provider,
15 created_at: session.user.created_at
16 })
17
18 analytics.track('User Signed In', {
19 method: session.user.app_metadata?.provider ?? 'email',
20 user_id: session.user.id
21 })
22 }
23
24 if (event === 'SIGNED_OUT') {
25 analytics.track('User Signed Out')
26 analytics.reset() // Clear Segment identity
27 }
28})

Expected result: Every sign-in creates an identify call and a track call in Segment. Sign-outs are tracked and the identity is reset.

3

Create an Edge Function to forward server-side events to Segment

For events that happen at the database level (new orders, profile updates, etc.), use a Supabase Edge Function that sends events to Segment's HTTP Tracking API. This function receives a webhook payload from Supabase and forwards it to Segment as a track call. Store your Segment Write Key as a Supabase secret so it is not exposed in code.

typescript
1// supabase/functions/segment-track/index.ts
2import { corsHeaders } from '../_shared/cors.ts'
3
4Deno.serve(async (req) => {
5 if (req.method === 'OPTIONS') {
6 return new Response('ok', { headers: corsHeaders })
7 }
8
9 const SEGMENT_WRITE_KEY = Deno.env.get('SEGMENT_WRITE_KEY')!
10 const payload = await req.json()
11
12 const segmentEvent = {
13 userId: payload.user_id || payload.record?.user_id,
14 event: payload.event_name || 'Database Event',
15 properties: {
16 table: payload.table,
17 type: payload.type,
18 ...payload.record
19 },
20 timestamp: new Date().toISOString()
21 }
22
23 const response = await fetch('https://api.segment.io/v1/track', {
24 method: 'POST',
25 headers: {
26 'Content-Type': 'application/json',
27 'Authorization': `Basic ${btoa(SEGMENT_WRITE_KEY + ':')}`
28 },
29 body: JSON.stringify(segmentEvent)
30 })
31
32 return new Response(
33 JSON.stringify({ success: response.ok }),
34 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
35 )
36})

Expected result: The Edge Function receives webhook payloads and forwards them to Segment's HTTP API. Each database event appears as a track call in your Segment debugger.

4

Set up a database webhook to trigger the Edge Function

In the Supabase Dashboard, go to Database > Webhooks and create a new webhook. Configure it to fire on INSERT events for the tables you want to track (for example, orders or subscriptions). Set the webhook URL to your Edge Function's URL. The webhook automatically sends the new row data as the request body, which the Edge Function then forwards to Segment.

typescript
1-- Alternatively, create the webhook via SQL
2select
3 supabase_functions.http_request(
4 'https://<project-ref>.supabase.co/functions/v1/segment-track',
5 'POST',
6 '{"Content-Type": "application/json"}',
7 '{}',
8 '5000'
9 );

Expected result: Every new INSERT on the configured table automatically triggers the Edge Function, which sends the event to Segment.

5

Track custom events from your application code

Beyond automated auth and database events, track custom user actions like button clicks, feature usage, and page views. Call analytics.track from your React components or event handlers. Include relevant properties like the Supabase user ID, the feature name, and any contextual data. This gives you a complete picture of user behavior in Segment.

typescript
1import { analytics } from './segment'
2import { createClient } from '@supabase/supabase-js'
3
4const supabase = createClient(
5 process.env.NEXT_PUBLIC_SUPABASE_URL!,
6 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
7)
8
9async function handleCreateProject(projectName: string) {
10 const { data: { user } } = await supabase.auth.getUser()
11
12 // Insert into Supabase
13 const { data, error } = await supabase
14 .from('projects')
15 .insert({ name: projectName, user_id: user?.id })
16 .select()
17 .single()
18
19 if (!error && data) {
20 // Track in Segment
21 analytics.track('Project Created', {
22 project_id: data.id,
23 project_name: projectName,
24 user_id: user?.id
25 })
26 }
27}

Expected result: Custom events appear in the Segment debugger with the properties you specified, and are routed to all connected analytics destinations.

Complete working example

segment-integration.ts
1import { AnalyticsBrowser } from '@segment/analytics-next'
2import { createClient } from '@supabase/supabase-js'
3
4// Initialize Segment
5export const analytics = AnalyticsBrowser.load({
6 writeKey: process.env.NEXT_PUBLIC_SEGMENT_WRITE_KEY!
7})
8
9// Initialize Supabase
10const supabase = createClient(
11 process.env.NEXT_PUBLIC_SUPABASE_URL!,
12 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
13)
14
15// Track auth events automatically
16export function initAuthTracking() {
17 supabase.auth.onAuthStateChange(async (event, session) => {
18 switch (event) {
19 case 'SIGNED_IN':
20 if (session?.user) {
21 analytics.identify(session.user.id, {
22 email: session.user.email,
23 provider: session.user.app_metadata?.provider,
24 created_at: session.user.created_at
25 })
26 analytics.track('User Signed In', {
27 method: session.user.app_metadata?.provider ?? 'email'
28 })
29 }
30 break
31 case 'SIGNED_OUT':
32 analytics.track('User Signed Out')
33 analytics.reset()
34 break
35 case 'USER_UPDATED':
36 if (session?.user) {
37 analytics.identify(session.user.id, {
38 email: session.user.email
39 })
40 analytics.track('User Profile Updated')
41 }
42 break
43 }
44 })
45}
46
47// Track a custom event
48export function trackEvent(name: string, properties?: Record<string, unknown>) {
49 analytics.track(name, properties)
50}
51
52// Track a page view
53export function trackPage(name: string, properties?: Record<string, unknown>) {
54 analytics.page(name, properties)
55}

Common mistakes when connecting Supabase to Segment

Why it's a problem: Hardcoding the Segment Write Key in Edge Function code instead of using Supabase secrets

How to avoid: Store the Write Key as a Supabase secret: supabase secrets set SEGMENT_WRITE_KEY=your_key. Access it with Deno.env.get('SEGMENT_WRITE_KEY').

Why it's a problem: Not calling analytics.reset() on sign-out, causing the next user's events to be attributed to the previous user

How to avoid: Always call analytics.reset() when the SIGNED_OUT event fires to clear the Segment anonymous ID and user identity.

Why it's a problem: Sending identify calls without the Supabase user ID, making it impossible to link events across sessions

How to avoid: Always pass session.user.id as the first argument to analytics.identify(). This links the Segment profile to the Supabase user.

Why it's a problem: Deploying the Edge Function without handling CORS, causing browser-based webhook tests to fail

How to avoid: Import and apply corsHeaders in your Edge Function. Handle OPTIONS preflight requests explicitly.

Best practices

  • Use analytics.identify with the Supabase user ID to create a consistent identity across all analytics tools
  • Track auth events automatically with onAuthStateChange instead of scattering track calls throughout your codebase
  • Store the Segment Write Key as a Supabase secret for Edge Functions — never hardcode it
  • Call analytics.reset() on sign-out to prevent cross-user event attribution
  • Use consistent event naming conventions like 'Object Action' (e.g., 'Project Created', 'File Uploaded')
  • Test events in the Segment debugger before connecting downstream destinations
  • Use database webhooks for server-side events that should be tracked regardless of which client initiated them

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I want to send Supabase auth events and database events to Segment for analytics. Show me how to use Analytics.js on the client to track sign-in and sign-out events, and how to create a Supabase Edge Function that forwards database webhook events to Segment's HTTP Tracking API.

Supabase Prompt

Set up a Supabase-to-Segment integration that tracks auth events with onAuthStateChange and analytics.identify/track on the client, and forwards database INSERT events from a webhook to Segment via an Edge Function using the HTTP Tracking API.

Frequently asked questions

Is the Segment Write Key safe to use in browser code?

Yes. The Segment Write Key is designed for client-side use, similar to the Supabase anon key. It can only send events to Segment, not read data. Use it in your frontend without concern.

Can I track Supabase Realtime events in Segment?

Yes. Subscribe to Realtime postgres_changes events and call analytics.track when events are received. This lets you track when other users' actions trigger updates visible to the current user.

How do I test that events are reaching Segment?

Use the Segment Debugger in the Segment Dashboard. It shows real-time incoming events with their properties, making it easy to verify your integration before connecting downstream destinations.

Can I send events to Segment from Supabase without an Edge Function?

For client-side events, use Analytics.js directly. For server-side database events, an Edge Function or external service is required because database triggers cannot make HTTP requests directly. The pg_net extension is an alternative for simple HTTP calls.

What happens if the Segment API is down when my Edge Function fires?

The Edge Function will receive an error from the Segment API. Implement retry logic or store failed events in a Supabase table for later processing. Segment also provides a batch API that can handle retries.

Can RapidDev help set up a complete analytics pipeline from Supabase to Segment?

Yes. RapidDev can design and implement your Segment integration including client-side tracking, Edge Function webhooks, event naming conventions, and downstream destination configuration.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.