Skip to main content
Technology & EngineeringAnalytics Services247 lines

Segment

Segment: customer data platform, event routing, identity resolution, analytics.js, server-side sources, warehouse destinations

Quick Summary21 lines
You are an expert in integrating Segment as a customer data platform for unified event collection and routing.

## Key Points

- Use Segment's tracking plan (Protocols) to define event schemas upfront. This prevents schema drift across teams and ensures data quality in all downstream destinations.
- Call `identify()` on every page load for logged-in users, not just at login. This ensures consistent identity stitching across client and server sources.
- Use the `integrations` object to control per-event destination routing rather than duplicating filtering logic in each downstream tool.

## Quick Example

```html
<script>
  !function(){var i="analytics",analytics=window[i]=window[i]||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","screen","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware","registerPlugin"];analytics.factory=function(e){return function(){if(window[i].initialized)return window[i][e].apply(window[i],arguments);var n=Array.prototype.slice.call(arguments);if(["track","screen","alias","group","page","identify"].indexOf(e)>-1){var c=document.querySelector("link[rel='canonical']");n.push({__t:"bpc",c:c&&c.getAttribute("href")||void 0,p:location.pathname,s:location.search,t:document.title,r:document.referrer})}n.unshift(e);analytics.push(n);return analytics}};for(var n=0;n<analytics.methods.length;n++){var key=analytics.methods[n];analytics[key]=analytics.factory(key)}analytics.load=function(key,n){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute("data-global-segment-analytics-key",i);t.src="https://cdn.segment.com/analytics.js/v2/"+key+"/analytics.min.js";var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(t,r);analytics._loadOptions=n};analytics._writeKey="YOUR_WRITE_KEY";analytics.load("YOUR_WRITE_KEY");analytics.page()}}();
</script>
```

```bash
npm install @segment/analytics-node
```
skilldb get analytics-services-skills/SegmentFull skill: 247 lines
Paste into your CLAUDE.md or agent config

Segment — Analytics Integration

You are an expert in integrating Segment as a customer data platform for unified event collection and routing.

Core Philosophy

Overview

Segment is a customer data platform (CDP) that acts as a single collection point for analytics events, then routes that data to hundreds of downstream destinations (analytics tools, data warehouses, marketing platforms, CRMs). Instead of installing multiple SDKs, you instrument Segment once and control data flow through its web UI. Segment provides identity resolution, data governance, and schema enforcement.

Setup & Configuration

Browser SDK (Analytics.js)

<script>
  !function(){var i="analytics",analytics=window[i]=window[i]||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","screen","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware","registerPlugin"];analytics.factory=function(e){return function(){if(window[i].initialized)return window[i][e].apply(window[i],arguments);var n=Array.prototype.slice.call(arguments);if(["track","screen","alias","group","page","identify"].indexOf(e)>-1){var c=document.querySelector("link[rel='canonical']");n.push({__t:"bpc",c:c&&c.getAttribute("href")||void 0,p:location.pathname,s:location.search,t:document.title,r:document.referrer})}n.unshift(e);analytics.push(n);return analytics}};for(var n=0;n<analytics.methods.length;n++){var key=analytics.methods[n];analytics[key]=analytics.factory(key)}analytics.load=function(key,n){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute("data-global-segment-analytics-key",i);t.src="https://cdn.segment.com/analytics.js/v2/"+key+"/analytics.min.js";var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(t,r);analytics._loadOptions=n};analytics._writeKey="YOUR_WRITE_KEY";analytics.load("YOUR_WRITE_KEY");analytics.page()}}();
</script>

Node.js Server-Side Source

npm install @segment/analytics-node
import { Analytics } from "@segment/analytics-node";

const analytics = new Analytics({
  writeKey: process.env.SEGMENT_WRITE_KEY!,
  // Optional: flush settings
  flushAt: 20,       // flush after 20 events
  flushInterval: 10000, // or every 10 seconds
});

// Graceful shutdown
process.on("SIGTERM", async () => {
  await analytics.closeAndFlush();
});

Next.js App Router Integration

// lib/segment-client.ts
"use client";
import { AnalyticsBrowser } from "@segment/analytics-next";

export const analytics = AnalyticsBrowser.load({
  writeKey: process.env.NEXT_PUBLIC_SEGMENT_WRITE_KEY!,
});

// components/SegmentProvider.tsx
"use client";
import { usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { analytics } from "@/lib/segment-client";

export function SegmentPageTracker() {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    analytics.page();
  }, [pathname, searchParams]);

  return null;
}

Core Patterns

Identify

// Client-side
analytics.identify("user-123", {
  email: "alice@example.com",
  name: "Alice Chen",
  plan: "pro",
  createdAt: "2025-01-15T10:00:00Z",
});

// Server-side (Node)
analytics.identify({
  userId: "user-123",
  traits: {
    email: "alice@example.com",
    name: "Alice Chen",
    plan: "pro",
    lifetimeValue: 1200,
  },
});

Track

// Client-side
analytics.track("Order Completed", {
  orderId: "order-789",
  revenue: 59.99,
  currency: "USD",
  products: [
    { id: "sku-1", name: "Widget", price: 29.99, quantity: 2 },
  ],
});

// Server-side
analytics.track({
  userId: "user-123",
  event: "Subscription Renewed",
  properties: {
    plan: "pro",
    mrr: 49.0,
    renewalCount: 3,
  },
});

Group (Company/Account)

analytics.group({
  userId: "user-123",
  groupId: "company-acme",
  traits: {
    name: "Acme Corp",
    industry: "Technology",
    plan: "enterprise",
    employees: 200,
  },
});

Middleware / Source Functions

Enrich or filter events before they reach destinations:

// Client-side middleware
import { AnalyticsBrowser } from "@segment/analytics-next";

const analytics = AnalyticsBrowser.load({
  writeKey: "YOUR_WRITE_KEY",
});

// Add context to every event
analytics.addSourceMiddleware(({ payload, next }) => {
  if (payload.obj.properties) {
    payload.obj.properties.appVersion = "2.4.1";
    payload.obj.properties.environment = process.env.NODE_ENV;
  }
  next(payload);
});

// PII filtering middleware
analytics.addSourceMiddleware(({ payload, next }) => {
  if (payload.obj.traits?.email) {
    // Hash email before sending
    payload.obj.traits.emailDomain = payload.obj.traits.email.split("@")[1];
    delete payload.obj.traits.email;
  }
  next(payload);
});

Tracking Plan Enforcement

Use Segment's Protocols to define a tracking plan and validate events:

// TypeScript types generated from your Segment tracking plan
interface TrackingPlan {
  "Order Completed": {
    orderId: string;
    revenue: number;
    currency: string;
    products: Array<{ id: string; name: string; price: number; quantity: number }>;
  };
  "Feature Used": {
    featureName: string;
    context: string;
  };
}

// Type-safe track wrapper
function track<E extends keyof TrackingPlan>(
  event: E,
  properties: TrackingPlan[E]
) {
  analytics.track(event, properties);
}

// Usage — compile-time validation
track("Order Completed", {
  orderId: "order-789",
  revenue: 59.99,
  currency: "USD",
  products: [{ id: "sku-1", name: "Widget", price: 29.99, quantity: 1 }],
});

Destination Filtering

Control which events reach which destinations via code:

// Send event only to specific destinations
analytics.track("Sensitive Action", { action: "delete-account" }, {
  integrations: {
    All: false,           // disable all destinations
    "Mixpanel": true,     // enable only Mixpanel
    "Google Analytics": true,
  },
});

Best Practices

  • Use Segment's tracking plan (Protocols) to define event schemas upfront. This prevents schema drift across teams and ensures data quality in all downstream destinations.
  • Call identify() on every page load for logged-in users, not just at login. This ensures consistent identity stitching across client and server sources.
  • Use the integrations object to control per-event destination routing rather than duplicating filtering logic in each downstream tool.

Common Pitfalls

  • Calling analytics.track() on the server without awaiting closeAndFlush() in serverless environments (Lambda, Vercel Functions) causes events to be lost when the process terminates before the batch is sent.
  • Sending events to all destinations by default leads to unexpected costs. New destinations added in the Segment UI receive all historical event types unless you configure destination filters. Review destination settings after enabling a new integration.

Anti-Patterns

Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.

Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.

Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.

Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.

Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.

Install this skill directly: skilldb add analytics-services-skills

Get CLI access →