Segment CDP Integration

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Segment CDP Integration

Segment is a Customer Data Platform: a single point for event collection that routes them to dozens of tools simultaneously. Instead of installing Mixpanel, Amplitude, Intercom, and Braze separately, you connect one SDK and configure destinations via UI. Key concepts — Sources (where from), Destinations (where to), Protocols (data contract).

Architecture

Browser / Server / Mobile
         │
    Segment Analytics.js / Node SDK
         │
    ┌────┴─────────────────────────┐
    │         Segment              │
    │  Sources → Protocols → ...   │
    └────┬─────────────────────────┘
         │
    ┌────┴──────────────────────────────────────────┐
    │  Destinations                                  │
    │  ├── Mixpanel (event analytics)               │
    │  ├── Amplitude (product analytics)            │
    │  ├── BigQuery (data warehouse)                │
    │  ├── Intercom (customer messaging)            │
    │  ├── Braze (marketing automation)             │
    │  ├── HubSpot (CRM)                           │
    │  └── Webhook (custom)                        │
    └───────────────────────────────────────────────┘

Installation of Analytics.js 2.0

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

export const analytics = AnalyticsBrowser.load({
  writeKey: import.meta.env.VITE_SEGMENT_WRITE_KEY,
  cdnURL: undefined, // custom proxy optional
}, {
  integrations: {
    'All': true,
    'Segment.io': {
      deliveryStrategy: {
        strategy: 'batching',
        config: {
          size: 10,
          timeout: 5000,
        },
      },
    },
  },
});

export default analytics;

CDN without bundler:

<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","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._writeKey=key;analytics._loadOptions=n};analytics.SNIPPET_VERSION="5.2.1";
analytics.load("YOUR_WRITE_KEY");
analytics.page();
}}();
</script>

Core Methods

Page

// Automatically — explicitly name for SPA
analytics.page('Product', 'Listing', {
  url: window.location.href,
  path: window.location.pathname,
  title: document.title,
  referrer: document.referrer,
  search: window.location.search,
  // custom properties
  category: 'electronics',
  locale: 'ru-RU',
});

Track

analytics.track('Order Completed', {
  order_id: 'ORDER-789',
  affiliation: 'Web Store',
  total: 14500,
  subtotal: 13500,
  revenue: 14500,
  shipping: 500,
  tax: 500,
  discount: 0,
  currency: 'RUB',
  products: [
    {
      product_id: 'SKU-001',
      sku: 'SKU-001',
      name: 'Professional Plan',
      price: 13500,
      quantity: 1,
      category: 'subscription',
    },
  ],
});

Segment follows ecommerce spec — naming events per spec auto-maps them to Destinations without extra setup.

Identify

analytics.identify('usr_12345', {
  email: '[email protected]',
  name: 'Ivan Petrov',
  plan: 'pro',
  company: {
    id: 'company_abc',
    name: 'Example Inc',
  },
  createdAt: '2024-01-15T10:00:00Z',
  // Product-specific traits
  projects_count: 5,
  last_login: new Date().toISOString(),
});

Group

// Attach user to organization (B2B)
analytics.group('company_abc', {
  name: 'Example Inc',
  industry: 'Technology',
  employees: 25,
  plan: 'enterprise',
  website: 'https://example.com',
});

Middleware for Event Enrichment

// Add context to all events
analytics.addSourceMiddleware(({ payload, next }) => {
  // Add app version
  payload.obj.context = {
    ...payload.obj.context,
    app: {
      version: APP_VERSION,
    },
    locale: navigator.language,
  };

  // Add AB variant
  const abVariant = localStorage.getItem('ab_variant');
  if (abVariant && payload.obj.properties) {
    payload.obj.properties.ab_variant = abVariant;
  }

  next(payload);
});

Server-side Source (Node.js / PHP)

For events that can't be tracked from frontend (webhook payment, subscription activation):

// Node.js
import { Analytics } from '@segment/analytics-node';

const analytics = new Analytics({
  writeKey: process.env.SEGMENT_SERVER_WRITE_KEY,
  flushAt: 20,
  flushInterval: 10000,
});

// Payment event from gateway
analytics.track({
  userId: 'usr_12345',
  event: 'Subscription Started',
  properties: {
    plan: 'pro',
    revenue: 2990,
    currency: 'RUB',
    billing_cycle: 'monthly',
    payment_method: 'card',
    mrr: 2990,
  },
  context: {
    ip: clientIp,
  },
});

// Must flush before process exit
process.on('SIGTERM', async () => {
  await analytics.closeAndFlush({ timeout: 5000 });
  process.exit(0);
});
// PHP via HTTP API
class SegmentService
{
    private string $writeKey;
    private string $endpoint = 'https://api.segment.io/v1/track';

    public function track(string $userId, string $event, array $properties = []): void
    {
        Http::withBasicAuth($this->writeKey, '')
            ->timeout(3)
            ->post($this->endpoint, [
                'userId'     => $userId,
                'event'      => $event,
                'properties' => $properties,
                'timestamp'  => now()->toIso8601String(),
                'messageId'  => uniqid('php_', true),
                'context'    => ['library' => ['name' => 'analytics-php']],
            ]);
    }
}

Protocols: Data Contract

Segment Protocols lets you define JSON Schema for each event — schema violations are logged and blocked:

{
  "name": "Order Completed",
  "description": "User completed checkout",
  "rules": {
    "required": ["order_id", "total", "currency"],
    "properties": {
      "order_id": { "type": "string" },
      "total": { "type": "number", "minimum": 0 },
      "currency": { "type": "string", "enum": ["RUB", "USD", "EUR"] },
      "products": {
        "type": "array",
        "items": {
          "required": ["product_id", "price"],
          "properties": {
            "product_id": { "type": "string" },
            "price": { "type": "number" }
          }
        }
      }
    }
  }
}

Invaluable for teams: developer can't accidentally send total: "14500" (string vs number) — Protocols rejects it and alerts.

Functions (Destination Functions)

When the needed Destination isn't in the catalog — write a Function in JS directly in UI:

// Segment Function — send to custom webhook
async function onTrack(event, settings) {
  if (event.event !== 'Order Completed') return;

  const response = await fetch(settings.webhookUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-API-Key': settings.apiKey },
    body: JSON.stringify({
      orderId: event.properties.order_id,
      userId: event.userId,
      revenue: event.properties.total,
      timestamp: event.timestamp,
    }),
  });

  if (!response.ok) {
    throw new Error(`Webhook failed: ${response.status}`);
  }
}

Timeline

Basic Analytics.js setup with page/track/identify — 1 day. Destination configuration (Mixpanel + BigQuery + CRM) — 2–3 days. Protocols and schema validation — 1 day. Server-side source + functions — 1–2 more days.