Segment Setup & Implementation | OpsBlu Docs

Segment Setup & Implementation

How to implement Segment as your customer data infrastructure. Covers Analytics.js 2.

Segment is not an analytics platform -- it is a customer data infrastructure layer that sits between your applications and your analytics, marketing, and data tools. When you call analytics.track('Purchase Completed'), Segment receives that event and fans it out to Google Analytics, Mixpanel, your data warehouse, your email platform, and any other connected destination simultaneously. This architecture means Segment implementation mistakes do not just affect one tool -- they propagate to every downstream destination. A malformed event, a broken identity call, or a misconfigured destination transforms a single implementation error into a multi-platform data crisis.

Why Proper Implementation Matters

Errors Multiply Across Destinations

Every event sent through Segment goes to every enabled destination:

  • A typo in an event name creates a phantom event in GA4, Amplitude, Mixpanel, and your warehouse simultaneously
  • An incorrect identify() call merges wrong user profiles across every downstream tool
  • A missing property breaks reports in every analytics platform that depends on it
  • PII accidentally sent through Segment reaches every connected destination, creating compliance issues across multiple systems

Schema Enforcement Prevents Downstream Chaos

Without schema enforcement (Protocols), Segment passes through any event with any properties:

  • Frontend developers can add events with arbitrary names and properties
  • Different teams may name the same event differently ("Purchase", "Order Completed", "Checkout Success")
  • Property types can change silently (price as string vs. number)
  • Destinations receive inconsistent data shapes, breaking automated reports and pipelines

Protocols is not optional for production implementations -- it is the mechanism that ensures data quality across your entire stack.

Device Mode vs. Cloud Mode

Segment delivers events to destinations via two methods:

Cloud Mode (server-to-server):

  • Events go: Browser -> Segment -> Destination API
  • Advantages: Fewer scripts on page, better privacy control, centralized delivery
  • Disadvantages: No access to browser-specific features (cookies, DOM, localStorage)

Device Mode (client-side bundling):

  • Events go: Browser -> Destination SDK (loaded by Segment) -> Destination
  • Advantages: Access to all destination features (remarketing pixels, session replay)
  • Disadvantages: More JavaScript on page, harder to control data flow

Choosing wrong mode for a destination means either missing features or bloating your page.

Pre-Implementation Planning

Access and Permissions

Segment Workspace:

  1. Sign in at app.segment.com
  2. Navigate to your workspace
  3. Request Workspace Owner or Source Admin access

Required Roles:

Role Permissions Use Case
Workspace Owner Full access, billing, user management Account admin
Source Admin Source creation, schema management Implementation lead
Protocols Admin Tracking plan enforcement, violations Data governance
Read-Only View sources, events, debugger Stakeholders

Write Keys (per source, per environment):

Environment Source Write Key Location
Development Web Dev Sources > Web Dev > Settings > API Keys
Staging Web Staging Sources > Web Staging > Settings > API Keys
Production Web Production Sources > Web Production > Settings > API Keys
Server Node.js Sources > Node.js > Settings > API Keys

Important: Each environment should have its own Segment source with its own write key. This prevents test data from flowing to production destinations.

Tracking Plan Design

The tracking plan is the most important artifact in a Segment implementation. Design it before writing any code:

Events:

Event API Call Properties Description
Page Viewed page() name, category, url, referrer User views any page
Signed Up track() signup_method, plan_type User creates account
Logged In track() login_method User authenticates
Product Viewed track() product_id, name, price, category User views product
Product Added track() product_id, name, price, quantity User adds to cart
Order Completed track() order_id, revenue, currency, products[] User completes purchase
Feature Activated track() feature_name, plan_required User engages feature

User Traits (sent via identify()):

Trait Type Description
email string User email address
name string Full name
plan string Subscription plan type
company object { name, id, industry, employee_count }
created_at datetime Account creation date

Group Traits (sent via group()):

Trait Type Description
name string Company name
industry string Industry vertical
plan string Account-level plan
employee_count number Company size

Destination Planning

Map each destination to its delivery mode and required events:

Destination Mode Events Needed Purpose
Google Analytics 4 Cloud All events Web analytics
Amplitude Cloud All events Product analytics
Facebook Pixel Device Page, Product, Order Ad attribution
Google Ads Device Order Completed Conversion tracking
Customer.io Cloud Identify, Track Email automation
BigQuery Cloud All events Data warehouse
Slack Cloud Order Completed Notifications

Implementation Walkthrough

Step 1: Install Analytics.js 2.0

npm Installation (recommended for SPAs):

npm install @segment/analytics-next
import { AnalyticsBrowser } from '@segment/analytics-next';

const analytics = AnalyticsBrowser.load({
  writeKey: 'YOUR_WRITE_KEY',
  // For EU data residency:
  // cdnURL: 'https://cdn.segment.com',
  // apiHost: 'api.segment.io/v1',
});

export default analytics;

Script Tag Installation:

<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",
  "register"];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,u:location.href,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/v1/"+key+"/analytics.min.js";
  var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(t,r);analytics._loadOptions=n};
  analytics._writeKey="YOUR_WRITE_KEY";analytics.SNIPPET_VERSION="5.2.0";
  analytics.load("YOUR_WRITE_KEY");
  analytics.page();
  }}();
</script>

Step 2: Implement Identity Resolution

// Anonymous page visit -- Segment auto-generates anonymousId
analytics.page('Home');

// After user authentication
function onUserLogin(user) {
  // Identify links anonymousId with userId across all destinations
  analytics.identify(user.id, {
    email: user.email,
    name: user.name,
    plan: user.plan,
    company: {
      name: user.company.name,
      id: user.company.id,
      industry: user.company.industry,
      employee_count: user.company.employeeCount
    },
    created_at: user.createdAt
  });

  // Group call for B2B account-level data
  analytics.group(user.company.id, {
    name: user.company.name,
    industry: user.company.industry,
    plan: user.company.plan,
    employee_count: user.company.employeeCount
  });
}

// On logout
function onUserLogout() {
  analytics.track('Logged Out');
  analytics.reset();  // Clears userId and generates new anonymousId
}

Identity Rules:

  • identify() should be called after every successful login
  • userId must be your internal, immutable user identifier (not email)
  • anonymousId is automatically generated and stored in a cookie/localStorage
  • reset() must be called on logout to prevent cross-user data leakage
  • Traits sent via identify() are cached and sent with subsequent track() calls in device mode

Step 3: Implement Page and Track Calls

Page Calls:

// Default page call (captures URL, title, referrer automatically)
analytics.page();

// Named page with properties
analytics.page('Products', 'Product Detail', {
  product_id: 'SKU-12345',
  product_name: 'Premium Widget',
  category: 'Widgets',
  price: 49.99
});

// SPA route change
router.afterEach((to) => {
  analytics.page(to.meta.category, to.meta.name, {
    path: to.path,
    url: window.location.href
  });
});

Track Calls:

// Product interaction
analytics.track('Product Added', {
  product_id: 'SKU-12345',
  name: 'Premium Widget',
  category: 'Widgets',
  price: 49.99,
  quantity: 1,
  currency: 'USD',
  cart_id: 'CART-789'
});

// Order completion (Segment e-commerce spec)
analytics.track('Order Completed', {
  order_id: 'ORD-2024-12345',
  total: 129.98,
  subtotal: 119.98,
  tax: 10.40,
  shipping: 5.99,
  discount: 6.39,
  coupon: 'SAVE10',
  currency: 'USD',
  products: [
    {
      product_id: 'SKU-12345',
      name: 'Premium Widget',
      price: 49.99,
      quantity: 1,
      category: 'Widgets',
      brand: 'Acme'
    },
    {
      product_id: 'SKU-67890',
      name: 'Deluxe Gadget',
      price: 79.99,
      quantity: 1,
      category: 'Gadgets',
      brand: 'Acme'
    }
  ]
});

// Feature usage
analytics.track('Feature Activated', {
  feature_name: 'Export Dashboard',
  plan_required: 'pro',
  export_format: 'csv'
});

// Form submission
analytics.track('Form Submitted', {
  form_name: 'Contact Us',
  form_id: 'contact-main',
  fields_completed: 5
});

Step 4: Server-Side Implementation

For backend events, use the Node.js source:

const Analytics = require('@segment/analytics-node');

const analytics = new Analytics({
  writeKey: 'YOUR_SERVER_WRITE_KEY',
  // For EU residency:
  // host: 'https://events.eu1.segmentapis.com',
});

// Server-side track call
analytics.track({
  userId: 'USR-12345',
  event: 'Subscription Renewed',
  properties: {
    plan_type: 'pro',
    revenue: 99.00,
    currency: 'USD',
    billing_period: 'annual',
    renewal_count: 3
  },
  timestamp: new Date().toISOString()
});

// Server-side identify (update traits)
analytics.identify({
  userId: 'USR-12345',
  traits: {
    subscription_status: 'active',
    mrr: 99.00,
    last_renewal: new Date().toISOString()
  }
});

// Flush before process exit
await analytics.closeAndFlush();

Step 5: Configure Protocols

Protocols enforces your tracking plan by validating events before delivery:

  1. In Segment, go to Protocols > Tracking Plans

  2. Create a new tracking plan (or import from CSV/JSON)

  3. For each event, define:

    • Event name: Exact name (case-sensitive)
    • Required properties: Must be present for the event to pass validation
    • Property types: String, Number, Boolean, Object, Array
    • Allowed values: Enum values for properties (optional)
  4. Connect tracking plan to sources:

    • Go to Protocols > Tracking Plans > Select plan > Connected Sources
    • Add your production web source
    • Choose violation handling:
      • Allow: Log violations but deliver events (recommended initially)
      • Block: Reject events that violate the plan (after validation period)
  5. Monitor violations:

    • Go to Protocols > Schema > Violations
    • Review events that fail validation
    • Fix implementation issues before switching to Block mode

Example Tracking Plan JSON:

{
  "events": [
    {
      "name": "Order Completed",
      "description": "User completes a purchase",
      "rules": {
        "properties": {
          "type": "object",
          "required": ["order_id", "total", "currency", "products"],
          "properties": {
            "order_id": { "type": "string" },
            "total": { "type": "number", "minimum": 0 },
            "currency": { "type": "string", "enum": ["USD", "EUR", "GBP"] },
            "products": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["product_id", "price"],
                "properties": {
                  "product_id": { "type": "string" },
                  "price": { "type": "number" }
                }
              }
            }
          }
        }
      }
    }
  ]
}

Step 6: Connect Destinations

For each downstream tool:

  1. Go to Connections > Destinations
  2. Click Add Destination
  3. Search and select the destination
  4. Connect it to your source
  5. Configure destination-specific settings:

Google Analytics 4:

  • Measurement ID: G-XXXXXXXXXX
  • Mode: Cloud mode (recommended)
  • Map Segment events to GA4 events

Amplitude:

  • API Key: Your Amplitude project API key
  • Mode: Cloud mode
  • Enable Group Analytics mapping (if using B2B)

Facebook Pixel:

  • Pixel ID: Your Facebook Pixel ID
  • Mode: Device mode (required for pixel functionality)
  • Map Segment events to FB standard events

BigQuery:

  • Project ID: Your GCP project
  • Dataset: Create or select
  • Mode: Cloud mode (warehouse sync)
  • Configure sync frequency
  1. Per-destination event filtering:
    • In destination settings, go to Mappings or Event Tester
    • Enable only the events this destination needs
    • Reduce unnecessary data delivery and costs

Step 7: Source Middleware (Data Transformation)

Use source middleware to transform events before they reach destinations:

// Add middleware during initialization
const analytics = AnalyticsBrowser.load({
  writeKey: 'YOUR_WRITE_KEY'
});

// Middleware to strip PII before events reach destinations
analytics.addSourceMiddleware(({ payload, next }) => {
  // Remove PII from track events
  if (payload.type === 'track') {
    delete payload.obj.properties?.email;
    delete payload.obj.properties?.phone;
    delete payload.obj.properties?.ip_address;
  }

  // Standardize event names
  if (payload.obj.event) {
    payload.obj.event = payload.obj.event
      .split(' ')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
      .join(' ');
  }

  next(payload);
});

Verification and QA

Segment Debugger

  1. In Segment, go to Connections > Sources > Select source > Debugger
  2. Perform actions on your website
  3. Events appear in real-time showing:
    • Event name and type (track, page, identify, group)
    • Full payload with properties
    • Delivery status to each destination
    • Any Protocols violations

Event Delivery

  1. Go to Connections > Destinations > Select destination
  2. Check Event Delivery tab
  3. Verify:
    • Events are delivered successfully (green status)
    • No delivery errors (red status with error messages)
    • Payload transformations are correct
    • Filtered events are not delivered (as expected)

End-to-End Testing

  1. Clear cookies and start a fresh session
  2. Browse several pages (verify page() calls in Debugger)
  3. Log in (verify identify() with correct traits)
  4. Perform tracked actions (verify track() with correct properties)
  5. Check each destination:
    • GA4: DebugView shows events
    • Amplitude: User Lookup shows events
    • BigQuery: Query recent events
    • Facebook: Test Events in Events Manager

Common Issues

Issue Cause Fix
Events not in Debugger Wrong write key Verify write key matches source environment
Events in Debugger but not in destination Destination filtering or error Check destination Event Delivery for errors
Device mode destination not loading Script blocked by ad blocker Expected behavior; no workaround for device mode
Identity not merging identify() called without userId Ensure userId is passed as first argument
Duplicate events Multiple analytics.js loads Ensure snippet is loaded only once
Protocols blocking events Tracking plan violation Check violation details, fix event payload
High event volume costs Unnecessary events flowing to all destinations Use destination filters and event mapping

Deployment Artifacts

  • Write keys: Per source, per environment (stored securely)
  • Tracking plan: Events, properties, types, and descriptions (maintained in Protocols)
  • Identity strategy: userId/anonymousId rules, group usage, reset behavior
  • Destination map: Connected destinations, delivery mode, event filters
  • Middleware configuration: Source and destination middleware for data transformation
  • Protocols rules: Tracking plan enforcement settings and violation handling
  • Server-side integration: Node.js source write key, authentication, flush configuration
  • Environment matrix: Sources, write keys, and destinations per environment

Linked Runbooks

Change Log and Owners

  • Document who manages Protocols tracking plans and approves new events
  • Track destination additions, removals, and configuration changes
  • Maintain write key rotation schedule
  • Record device mode vs. cloud mode decisions with rationale
  • Review quarterly: event delivery rates, Protocols violations, destination costs