OneApp Docs
PackagesIntegrations

@repo/3p-segment

Complete Segment CDP integration with 300+ destination support. Track once, route everywhere. Events, identify, page, group tracking. Data warehouse integration. Client, server, and edge runtime support.

Quick Start

Add Segment in 3 minutes:

pnpm add @repo/3p-segment

CDP, 300+ destinations, warehouse integration included. Skip to Quick Start →

Why @repo/3p-segment?

Each analytics service needs separate setup. Google Analytics tracking duplicated from Mixpanel tracking. Data warehouse ETL scripts for every source. Destination configurations scattered across apps. No unified customer data platform. Breaking changes affect multiple integrations.

@repo/3p-segment solves this by centralizing all analytics routing through Segment's CDP—track once, send to 300+ destinations automatically.

Production-ready with events, identify, page, group tracking, 300+ destinations, warehouse integration, GDPR compliance, and ~12KB bundle size.

Use cases

  • Customer data platform — Track once, route to 300+ destinations (GA, Mixpanel, Amplitude, Slack)
  • Data warehousing — Auto-sync events to Snowflake, BigQuery, Redshift
  • Account tracking — Group-level analytics for B2B companies
  • E-commerce analytics — Product views, cart adds, purchases with standard schema
  • Privacy compliance — GDPR/CCPA with consent management

How it works

@repo/3p-segment provides unified CDP tracking:

// Client setup
import { SegmentProvider, useAnalytics } from "@repo/3p-segment/client";

function App() {
  return (
    <SegmentProvider writeKey={process.env.NEXT_PUBLIC_SEGMENT_KEY!}>
      <MyApp />
    </SegmentProvider>
  );
}

// Track once, route everywhere
function Button() {
  const analytics = useAnalytics();

  const handlePurchase = () => {
    analytics.track("Purchase Completed", {
      order_id: "ord_123",
      total: 99.99,
    });
    // → Sends to Google Analytics, Mixpanel, Amplitude, warehouse
  };

  return <button onClick={handlePurchase}>Purchase</button>;
}

Uses @segment/analytics-next for client, @segment/analytics-node for server, and Segment's CDP for multi-destination routing.

Key features

300+ destinations — Google Analytics, Mixpanel, Amplitude, Slack, warehouse

Data warehousing — Auto-sync to Snowflake, BigQuery, Redshift

Group tracking — Account-level analytics for B2B companies

E-commerce schema — Product views, carts, checkouts with standard spec

Privacy controls — GDPR/CCPA with consent management

Multiple runtimes — Browser, Node.js, Edge, Next.js support

Quick Start

1. Install the package

pnpm add @repo/3p-segment

2. Set up client provider

app/providers.tsx
"use client";

import { SegmentProvider } from "@repo/3p-segment/client";

export function Providers({ children }) {
  return (
    <SegmentProvider writeKey={process.env.NEXT_PUBLIC_SEGMENT_KEY!}>
      {children}
    </SegmentProvider>
  );
}

3. Track events

app/components/ProductCard.tsx
"use client";

import { useAnalytics } from "@repo/3p-segment/client";

export function ProductCard({ product }) {
  const analytics = useAnalytics();

  const handleView = () => {
    analytics.track("Product Viewed", {
      product_id: product.id,
      name: product.name,
      price: product.price,
      category: product.category,
    });
  };

  return <div onMouseEnter={handleView}>{product.name};
}

4. Identify users

app/components/Auth.tsx
"use client";

import { useAnalytics } from "@repo/3p-segment/client";
import { useEffect } from "react";

export function UserIdentification({ user }) {
  const analytics = useAnalytics();

  useEffect(() => {
    analytics.identify(user.id, {
      email: user.email,
      name: user.name,
      plan: user.plan,
      company: user.company
    });
  }, [user]);

  return null;
}

That's it! Your events now route to all configured Segment destinations (Google Analytics, Mixpanel, warehouse, etc.).

Server-side analytics

Use SegmentServerAnalytics for server-side tracking:

import { SegmentServerAnalytics } from "@repo/3p-segment/server";

export const analytics = new SegmentServerAnalytics({
  writeKey: process.env.SEGMENT_KEY!,
  flushAt: 20,
  flushInterval: 10000
});

await analytics.track("Server Event", { user_id: "123" });

Technical Details

For Developers: Technical implementation details

Overview

PropertyValue
Locationpackages/3p-segment
Dependencies@segment/analytics-next, @segment/analytics-node
FeaturesEvents, Identify, Page, Group, Destinations, Warehouse
RuntimesBrowser, Node.js, Edge, Next.js
Bundle Size~12KB (with tree-shaking)

Export Paths

PathDescription
@repo/3p-segmentMain exports & utilities
@repo/3p-segment/adapterSegment adapter class
@repo/3p-segment/clientBrowser/Next.js client
@repo/3p-segment/serverNode.js server
@repo/3p-segment/configConfiguration types

Event Tracking

Basic Track Events

"use client";
import { useAnalytics } from "@repo/3p-segment/client";

export function TrackingComponent() {
  const analytics = useAnalytics();

  const handlePurchase = () => {
    // highlight-start
    analytics.track("Purchase Completed", {
      order_id: "ord_123",
      total: 99.99,
      currency: "USD",
      items: [
        {
          product_id: "prod_456",
          quantity: 2,
          price: 49.99,
        },
      ],
    });
    // highlight-end
  };

  return <button onClick={handlePurchase}>Complete Purchase</button>;
}

E-commerce Events

// Product browsing
analytics.track("Product Viewed", {
  product_id: "prod_123",
  sku: "SKU-123",
  category: "Electronics",
  name: "Premium Headphones",
  brand: "AudioTech",
  price: 199.99,
  currency: "USD",
  image_url: "https://example.com/headphones.jpg",
  url: "https://example.com/products/headphones"
});

// Add to cart
analytics.track("Product Added", {
  product_id: "prod_123",
  sku: "SKU-123",
  category: "Electronics",
  name: "Premium Headphones",
  brand: "AudioTech",
  price: 199.99,
  quantity: 1,
  currency: "USD"
});

// Checkout
analytics.track("Checkout Started", {
  order_id: "ord_123",
  affiliation: "Online Store",
  total: 199.99,
  revenue: 199.99,
  shipping: 10.0,
  tax: 0.0,
  discount: 0.0,
  coupon: "WELCOME10",
  currency: "USD",
  products: [
    {
      product_id: "prod_123",
      sku: "SKU-123",
      name: "Premium Headphones",
      price: 199.99,
      quantity: 1,
      category: "Electronics"
    }
  ]
});

// Order completed
analytics.track("Order Completed", {
  order_id: "ord_123",
  affiliation: "Online Store",
  value: 199.99,
  revenue: 199.99,
  shipping: 10.0,
  tax: 0.0,
  discount: 0.0,
  coupon: "WELCOME10",
  currency: "USD",
  products: [
    {
      product_id: "prod_123",
      sku: "SKU-123",
      name: "Premium Headphones",
      price: 199.99,
      quantity: 1,
      category: "Electronics"
    }
  ]
});

Custom Events

analytics.track("Feature Used", {
  feature_name: "advanced_analytics",
  feature_tier: "enterprise",
  duration_seconds: 45,
  success: true
});

User Identification

Identify Users

"use client";
import { useAnalytics } from "@repo/3p-segment/client";

export function UserIdentification() {
  const analytics = useAnalytics();

  useEffect(() => {
    // highlight-start
    analytics.identify(user.id, {
      email: user.email,
      name: user.name,
      phone: user.phone,
      company: user.company,
      plan: user.plan,
      lifecycle_stage: "customer",
      sign_up_date: user.created_at,
      mrr: user.monthly_revenue
    });
    // highlight-end
  }, [user]);

  return null;
}

Server-Side Identification

import { analytics } from "#/lib/analytics";

await analytics.identify(user.id, {
  email: user.email,
  name: user.name,
  traits: {
    company: user.company,
    plan: user.plan,
    annual_revenue: user.revenue
  }
});

Update User Traits

// Update existing user
analytics.identify(user.id, {
  plan: "premium", // Plan changed
  upgrade_date: new Date().toISOString()
});

Page Views

Track Page Views

"use client";
import { useAnalytics } from "@repo/3p-segment/client";
import { useEffect } from "react";
import { usePathname } from "next/navigation";

export function PageViewTracker() {
  const analytics = useAnalytics();
  const pathname = usePathname();

  useEffect(() => {
    // highlight-start
    analytics.page("Page Viewed", {
      title: document.title,
      url: window.location.href,
      path: pathname,
      referrer: document.referrer
    });
    // highlight-end
  }, [pathname, analytics]);

  return null;
}

Named Page Views

analytics.page("Checkout", {
  step: 2,
  payment_method: "credit_card"
});

analytics.page("Product Page", {
  product_id: "prod_123",
  category: "Electronics"
});

Group Analytics

Account-Level Tracking

// Track company/account activity
analytics.group("company_123", {
  name: "Acme Corp",
  industry: "Technology",
  employees: 500,
  plan: "enterprise",
  annual_revenue: 10000000
});

// Then track company events
analytics.track("Feature Used", {
  feature: "api_access",
  timestamp: Date.now()
});
// Event associated with company_123

Update Group Traits

analytics.group("company_123", {
  plan: "enterprise_plus", // Plan upgrade
  upgraded_date: new Date().toISOString(),
  total_seats: 100
});

Destinations

Multi-Destination Routing

// Single track() call sends to ALL enabled destinations
// E.g., Google Analytics, Mixpanel, Amplitude, Slack, etc.

analytics.track("Purchase", {
  order_id: "ord_123",
  value: 99.99
});

// Segment automatically routes to:
// - Analytics warehouse
// - Google Analytics
// - Mixpanel
// - Amplitude
// - Slack (if configured)
// - ... 300+ other destinations

Destination-Specific Properties

analytics.track("Purchase", {
  // Standard properties
  order_id: "ord_123",
  value: 99.99,

  // Mixpanel-specific
  mixpanel: {
    distinct_id: user.id,
    token: "mixpanel-token"
  },

  // Custom destination payload
  integrations: {
    "Google Analytics": true,
    Mixpanel: true,
    Amplitude: false // Skip this destination
  }
});

Data Warehouse

Track for Warehouse

// All events automatically flow to warehouse if connected
analytics.track("User Activity", {
  user_id: user.id,
  event_timestamp: new Date().toISOString(),
  session_id: sessionId,
  properties: {
    page: pathname,
    referrer: document.referrer,
    user_agent: navigator.userAgent
  }
});

// Query in warehouse (e.g., Snowflake, BigQuery)
// SELECT * FROM events WHERE event = 'User Activity' ORDER BY event_timestamp

Dimensional Data

// Identify provides dimension data
analytics.identify(user.id, {
  dimension_user_id: user.id,
  dimension_company_id: user.company_id,
  dimension_plan: user.plan,
  dimension_signup_date: user.created_at
});

// Query in warehouse
// SELECT u.dimension_plan, COUNT(*) FROM users u GROUP BY dimension_plan

Privacy & Compliance

"use client";
import { useAnalytics } from "@repo/3p-segment/client";

export function PrivacyConsent() {
  const analytics = useAnalytics();

  const handleConsentGranted = () => {
    // Enable tracking
    analytics.load(process.env.NEXT_PUBLIC_SEGMENT_KEY!);
  };

  const handleConsentRevoked = () => {
    // Disable tracking
    analytics.reset();
  };

  return (
    <>
      <button onClick={handleConsentGranted}>Accept Analytics</button>
      <button onClick={handleConsentRevoked}>Reject Analytics</button>
    </>
  );
}

Do Not Track Respect

if (navigator.doNotTrack === "1") {
  analytics.reset(); // Disable tracking
}

Advanced Patterns

Batching Events (Server)

import { analytics } from "#/lib/analytics";

// Accumulate events
const events = [];
for (const user of users) {
  events.push({
    event: "User Activity",
    userId: user.id,
    properties: { action: "viewed_page" }
  });
}

// Batch send automatically via batching
await analytics.flush();

Retry with Fallback

import { withRetry } from "@repo/3p-core/composable/with-retry";
import { SegmentAdapter } from "@repo/3p-segment/adapter";

const adapter = new SegmentAdapter({
  provider: "segment",
  writeKey: process.env.SEGMENT_KEY!
});

const resilient = withRetry(adapter, {
  maxRetries: 3,
  backoffMultiplier: 2
});

await resilient.track({ name: "Important Event" });

Privacy Wrapper

import { withPrivacy } from "@repo/3p-core/composable/with-privacy";

const compliant = withPrivacy(adapter, {
  anonymizeIp: true,
  gdprCompliant: true
});

// PII automatically filtered
await compliant.identify(userId, {
  email: "user@example.com", // Will be removed
  userId: "123" // Will be hashed
});

Configuration

Environment Variables

# Client key (public)
NEXT_PUBLIC_SEGMENT_KEY=xxxxxxxxxxxxx

# Server key (secret)
SEGMENT_KEY=xxxxxxxxxxxxx

Advanced Options

<SegmentProvider
  writeKey={process.env.NEXT_PUBLIC_SEGMENT_KEY!}
  options={{
    integrations: {
      "Segment.io": {
        apiHost: "https://api.segment.io",
      },
    },
    flushInterval: 5000,
    maxQueueSize: 20000,
  }}
>
  {children}
</SegmentProvider>

Testing

Mock Segment in Tests

import { vi } from "vitest";

vi.mock("@repo/3p-segment/client", () => ({
  useAnalytics: () => ({
    track: vi.fn(),
    identify: vi.fn(),
    page: vi.fn(),
    group: vi.fn(),
  }),
}));

describe("Analytics", () => {
  it("tracks page view", () => {
    const { page } = useAnalytics();
    render(<Component />);
    expect(page).toHaveBeenCalledWith("Page Viewed", expect.any(Object));
  });
});

Troubleshooting

Events Not Appearing in Warehouse

# 1. Verify write key
echo $NEXT_PUBLIC_SEGMENT_KEY

# 2. Check Segment dashboard
# Settings → Sources → Check event volume

# 3. Verify warehouse connection
# Settings → Warehouse → Check sync status

# 4. Check network requests
# DevTools Network → Look for api.segment.io requests

Destination Not Receiving Events

// 1. Check destination is enabled in Segment dashboard
// 2. Verify mapping configuration
// 3. Check integrations flag
analytics.track("Event", {
  integrations: {
    "Google Analytics": true // Explicitly enable
  }
});

Performance Tips

  • Batch events on server-side (reduces API calls)
  • Implement retry logic for reliability
  • Use groups for account-level analytics
  • Set flushInterval based on traffic volume
  • Monitor event volume in Segment dashboard

External Resources

On this page