Иконка подарка

Весенняя распродажа! Скидка 15% по промокоду

до 01.04.2026

Сегмент hooks - библиотека hooks-segment для интеграции Segment в React

27 марта 2026
Автор

Олег Марков

Введение

Сегмент hooks (или библиотека hooks-segment) — это удобный способ интеграции аналитической платформы Segment в React‑приложения через хуки. Вместо того чтобы напрямую обращаться к глобальному объекту analytics, вы можете использовать понятные React-хуки, которые лучше вписываются в архитектуру современного фронтенда.

Задача этой статьи — показать, как с помощью hooks-segment:

  • инициализировать Segment в React-приложении;
  • отправлять события;
  • отслеживать просмотры страниц (screen / page view);
  • работать с пользователем (identify, group, alias);
  • удобно пользоваться типизацией и контекстом.

Смотрите, я покажу вам, как это работает по шагам: от базовой интеграции до продвинутых сценариев.


Что такое hooks-segment и зачем он нужен

Кратко о Segment

Segment — это платформа для сбора и маршрутизации аналитических данных. Основная идея:

  • вы отправляете события в единый SDK Segment;
  • Segment перенаправляет эти данные в десятки интеграций: Amplitude, Mixpanel, GA4, BI-системы и т. д.;
  • вам не нужно встраивать каждую аналитическую систему отдельно.

В вебе Segment обычно использует JavaScript SDK с глобальным объектом analytics:

analytics.track('Product Viewed', { productId: '123' })

Но такой подход не всегда удобно использовать в React:

  • нет явной зависимости в коде (глобальная переменная);
  • сложно тестировать;
  • сложно типизировать;
  • неудобно использовать в хук-ориентированных архитектурах.

Что дает hooks-segment

hooks-segment оборачивает Segment API в React-контекст и хуки. Обычно библиотека предоставляет:

  • провайдер, который инициализирует Segment и прокидывает его в контекст;
  • хук для получения инстанса Segment (useSegment / useSegmentAnalytics);
  • специализированные хуки для:
    • отправки событий (track);
    • идентификации пользователя (identify);
    • отслеживания страниц (page / screen);
    • группировки (group);
    • связывания анонимного и авторизованного пользователя (alias).

В итоге вы получаете:

  • явную зависимость — хуки импортируются из библиотеки;
  • лучшую тестируемость — контекст можно замокать;
  • поддержку SSR/Next.js благодаря контролируемой инициализации;
  • более чистый и предсказуемый код.

Установка и базовая конфигурация hooks-segment

Установка библиотеки

Обычно пакет устанавливается через npm или yarn. Конкретное имя может отличаться, но для статьи будем использовать условное название hooks-segment:

npm install hooks-segment
# или
yarn add hooks-segment

Если вы используете TypeScript, убедитесь, что у пакета есть типы. Чаще всего они уже включены, но иногда придется установить @types/segment-analytics.

Инициализация Segment через провайдер

Главная идея — обернуть все приложение в провайдер, который инициализирует Segment и хранит инстанс SDK в React-контексте.

Давайте разберемся на примере:

// src/analytics/SegmentProvider.tsx
import React from 'react'
import { SegmentProvider } from 'hooks-segment'

// Здесь мы передаем настройки Segment в провайдер
const segmentWriteKey = process.env.REACT_APP_SEGMENT_WRITE_KEY as string

export const AppSegmentProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  return (
    <SegmentProvider writeKey={segmentWriteKey} options={{ debug: false }}>
      {/* Внутри провайдера будет доступ к хукам hooks-segment */}
      {children}
    </SegmentProvider>
  )
}

Теперь оборачиваем приложение:

// src/index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { AppSegmentProvider } from './analytics/SegmentProvider'
import { App } from './App'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)

root.render(
  <React.StrictMode>
    {/* Здесь мы оборачиваем все приложение в AppSegmentProvider */}
    <AppSegmentProvider>
      <App />
    </AppSegmentProvider>
  </React.StrictMode>
)

Комментарий к коду:

  • SegmentProvider внутри инициализирует Segment с вашим writeKey;
  • все дочерние компоненты могут вызывать хуки из hooks-segment;
  • вы централизуете конфигурацию и исключаете дублирование.

Если вы используете Next.js, провайдер лучше подключать в _app.tsx или layout.tsx (для нового App Router).


Основные хуки hooks-segment

В этом разделе вы увидите, как пользоваться ключевыми хуками. Названия могут немного отличаться в конкретной реализации, но сама структура обычно похожа.

Получение инстанса Segment — useSegment

Многие библиотеки предоставляют хук общего вида useSegment (или useSegmentAnalytics), который возвращает объект с методами Segment: track, identify, page, group и т. д.

Покажу вам, как это реализовано на практике:

// src/hooks/useAnalytics.ts
import { useSegment } from 'hooks-segment'

// Этот хук просто реэкспортирует функционал Segment
export const useAnalytics = () => {
  const analytics = useSegment()

  // Здесь мы можем добавить свои обертки, если нужно
  return analytics
}

Пример использования:

// src/components/ButtonBuy.tsx
import React from 'react'
import { useAnalytics } from '../hooks/useAnalytics'

interface ButtonBuyProps {
  productId: string
}

export const ButtonBuy: React.FC<ButtonBuyProps> = ({ productId }) => {
  const analytics = useAnalytics()

  const handleClick = () => {
    // Здесь мы отправляем событие "Product Added" в Segment
    analytics.track('Product Added', {
      productId,
      source: 'product_page',
    })
  }

  return (
    <button onClick={handleClick}>
      Добавить в корзину
    </button>
  )
}

Обратите внимание, как этот фрагмент кода решает задачу:

  • компонент не знает о глобальном объекте analytics;
  • мы можем замокать useAnalytics в тестах;
  • события отправляются только внутри React-контекста.

Отправка событий — track

Метод track — один из основных. Он отправляет в Segment событие с названием и опциональными свойствами.

Теория:

  • event — строка, отражающая действие пользователя: Product Viewed, Checkout Started;
  • properties — объект с данными о событии (идентификаторы, цены, категории);
  • события лучше стандартизировать и документировать — это облегчает аналитику.

Теперь вы увидите, как это выглядит в коде:

// src/analytics/useTrack.ts
import { useSegment } from 'hooks-segment'

export const useTrack = () => {
  const analytics = useSegment()

  const trackProductViewed = (params: { productId: string; category?: string }) => {
    // Здесь мы используем track для конкретного бизнес-события
    analytics.track('Product Viewed', {
      productId: params.productId,
      category: params.category,
    })
  }

  const trackAddToCart = (params: { productId: string; price: number }) => {
    analytics.track('Product Added To Cart', {
      productId: params.productId,
      price: params.price,
      currency: 'USD',
    })
  }

  // Возвращаем набор доменных трекеров
  return { trackProductViewed, trackAddToCart }
}

Используем в компоненте:

// src/components/ProductCard.tsx
import React, { useEffect } from 'react'
import { useTrack } from '../analytics/useTrack'

interface ProductCardProps {
  productId: string
  category?: string
  price: number
}

export const ProductCard: React.FC<ProductCardProps> = ({ productId, category, price }) => {
  const { trackProductViewed, trackAddToCart } = useTrack()

  useEffect(() => {
    // Здесь мы отслеживаем просмотр карточки товара
    trackProductViewed({ productId, category })
  }, [productId, category, trackProductViewed])

  const handleAddToCart = () => {
    // Здесь мы отслеживаем добавление товара в корзину
    trackAddToCart({ productId, price })
  }

  return (
    <div>
      <button onClick={handleAddToCart}>
        В корзину
      </button>
    </div>
  )
}

Так вы выносите сырые вызовы analytics.track из компонентов в отдельный слой аналитики. Это облегчает рефакторинг и изменение схемы событий.


Идентификация пользователя — identify

identify связывает действия с конкретным пользователем. Обычно вызывается после:

  • регистрации;
  • логина;
  • получения профиля с backend.

Как работает теория:

  • userId — стабильный идентификатор пользователя (обычно из БД);
  • traits — свойства пользователя (email, тарифный план, роль, страна).

Давайте посмотрим, что происходит в следующем примере:

// src/analytics/useIdentify.ts
import { useSegment } from 'hooks-segment'

export const useIdentify = () => {
  const analytics = useSegment()

  const identifyUser = (params: {
    userId: string
    email?: string
    name?: string
    plan?: string
  }) => {
    // Здесь мы связываем текущие события с конкретным userId
    analytics.identify(params.userId, {
      email: params.email,
      name: params.name,
      plan: params.plan,
    })
  }

  return { identifyUser }
}

Использование после логина:

// src/components/LoginForm.tsx
import React from 'react'
import { useIdentify } from '../analytics/useIdentify'

export const LoginForm: React.FC = () => {
  const { identifyUser } = useIdentify()

  const handleLoginSuccess = (user: { id: string; email: string; name: string }) => {
    // Здесь мы вызываем identify, когда backend подтвердил логин
    identifyUser({
      userId: user.id,
      email: user.email,
      name: user.name,
      plan: 'free',
    })
  }

  // Здесь может быть реальная логика логина
  return (
    <form>
      {/* Поля ввода опущены для краткости */}
      <button type="submit">
        Войти
      </button>
    </form>
  )
}

Важно:

  • вызывать identify только после успешной аутентификации;
  • не использовать временный или локальный ID для userId;
  • не передавать чувствительные данные в traits.

Отслеживание экранов и страниц — page / screen

В веб-приложениях Segment использует метод page, в мобильных — screen. Многие React-приложения используют роутинг, и нам нужно автоматически отправлять события при смене страницы.

Предположим, библиотека hooks-segment предоставляет хук usePage. Если такого хука нет, вы можете использовать useSegment и самостоятельно вызывать analytics.page.

Смотрите, я покажу вам, как это работает с React Router:

// src/analytics/usePageTracking.ts
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { useSegment } from 'hooks-segment'

export const usePageTracking = () => {
  const location = useLocation()
  const analytics = useSegment()

  useEffect(() => {
    // Здесь мы вызываем page при каждом изменении пути
    analytics.page(undefined, undefined, {
      path: location.pathname,
      search: location.search,
    })
  }, [location.pathname, location.search, analytics])
}

Теперь подключаем этот хук в верхнем уровне приложения:

// src/App.tsx
import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { usePageTracking } from './analytics/usePageTracking'
import { HomePage } from './pages/HomePage'
import { ProductPage } from './pages/ProductPage'

export const App: React.FC = () => {
  // Здесь мы активируем глобальное отслеживание страниц
  usePageTracking()

  return (
    <BrowserRouter>
      <Routes>
        {/* Здесь настраиваем маршруты приложения */}
        <Route path="/" element={<HomePage />} />
        <Route path="/product/:id" element={<ProductPage />} />
      </Routes>
    </BrowserRouter>
  )
}

Комментарии:

  • usePageTracking — чистый хук, который не зависит от UI;
  • он срабатывает при каждом изменении location, отправляя событие page;
  • в properties можно добавить больше информации: title, category, referrer.

Если вы работаете с React Native или мобильным окружением, вместо URL можно использовать названия экранов и параметры навигации.


Группы и alias — group и alias

Группировка пользователей — group

Метод group объединяет пользователей в сущности вроде:

  • организация;
  • команда;
  • компания;
  • подписка.

Это полезно для B2B-сценариев, когда аналитика строится по компаниям, а не только по отдельным пользователям.

Пример:

// src/analytics/useGroup.ts
import { useSegment } from 'hooks-segment'

export const useGroup = () => {
  const analytics = useSegment()

  const groupUserToCompany = (params: {
    groupId: string
    name: string
    plan?: string
  }) => {
    // Здесь мы связываем пользователя с конкретной группой (компанией)
    analytics.group(params.groupId, {
      name: params.name,
      plan: params.plan,
    })
  }

  return { groupUserToCompany }
}

Вызывается, например, после выбора организации или при логине в multi-tenant‑системе.

alias — связывание анонимного и авторизованного пользователя

alias нужен для связывания:

  • анонимных событий (до регистрации);
  • с авторизованным пользователем (после регистрации).

В браузере Segment обычно автоматически генерирует anonymousId. Когда пользователь регистрируется, вы хотите, чтобы его pre-signup действия сохранились и были связаны с его новым userId.

Давайте разберемся на примере:

// src/analytics/useAlias.ts
import { useSegment } from 'hooks-segment'

export const useAlias = () => {
  const analytics = useSegment()

  const aliasUser = (newUserId: string) => {
    // Здесь мы связываем существующую анонимную личность с новым UserID
    analytics.alias(newUserId)
  }

  return { aliasUser }
}

Шаблонный сценарий:

  1. Пользователь выполняет действия как гость — вы вызываете track, page, но без identify.
  2. Пользователь регистрируется.
  3. Вы вызываете alias(newUserId).
  4. Вызываете identify(newUserId, traits...).

Это позволяет аналитике корректно объединить историю событий.


Архитектура и лучшие практики интеграции hooks-segment

Разделение доменного уровня и SDK

Вместо того чтобы вызывать useSegment в каждом компоненте, есть смысл:

  • создать слой аналитических хуков/сервисов;
  • внутри этого слоя использовать объекты Segment;
  • наружу отдавать только бизнес-события.

Обратите внимание, как это выглядит:

// src/analytics/events.ts
export enum AnalyticsEventName {
  ProductViewed = 'Product Viewed',
  ProductAddedToCart = 'Product Added To Cart',
  CheckoutStarted = 'Checkout Started',
}
// src/analytics/useShopAnalytics.ts
import { useSegment } from 'hooks-segment'
import { AnalyticsEventName } from './events'

export const useShopAnalytics = () => {
  const analytics = useSegment()

  const trackProductViewed = (productId: string) => {
    analytics.track(AnalyticsEventName.ProductViewed, { productId })
  }

  const trackAddToCart = (productId: string, price: number) => {
    analytics.track(AnalyticsEventName.ProductAddedToCart, {
      productId,
      price,
    })
  }

  const trackCheckoutStarted = (cartId: string, amount: number) => {
    analytics.track(AnalyticsEventName.CheckoutStarted, {
      cartId,
      amount,
    })
  }

  return {
    trackProductViewed,
    trackAddToCart,
    trackCheckoutStarted,
  }
}

Использование в UI:

// src/components/CartButton.tsx
import React from 'react'
import { useShopAnalytics } from '../analytics/useShopAnalytics'

export const CartButton: React.FC = () => {
  const { trackCheckoutStarted } = useShopAnalytics()

  const handleClick = () => {
    // Здесь мы отправляем событие старта оформления заказа
    trackCheckoutStarted('cart-123', 99.9)
  }

  return (
    <button onClick={handleClick}>
      Оформить заказ
    </button>
  )
}

Преимущества:

  • все события сконцентрированы в одном месте;
  • легче поддерживать схемы и проверять, что события соответствуют требованиям продукта;
  • меньше связности между компонентами и Segment SDK.

Работа с TypeScript

hooks-segment в связке с TypeScript позволяет сделать трекинг более безопасным.

Подход:

  1. Заводим типы для событий и их свойств.
  2. Пишем обертку над track, которая принимает только известные события.

Пример:

// src/analytics/types.ts
export type AnalyticsEvent =
  | {
      name: 'Product Viewed'
      properties: { productId: string; category?: string }
    }
  | {
      name: 'Product Added To Cart'
      properties: { productId: string; price: number }
    }
  | {
      name: 'Checkout Started'
      properties: { cartId: string; amount: number }
    }
// src/analytics/useTypedTrack.ts
import { useSegment } from 'hooks-segment'
import { AnalyticsEvent } from './types'

export const useTypedTrack = () => {
  const analytics = useSegment()

  const trackEvent = (event: AnalyticsEvent) => {
    // Здесь TypeScript проверяет соответствие имени события и свойств
    analytics.track(event.name, event.properties)
  }

  return { trackEvent }
}

Использование:

// src/components/TypedExample.tsx
import React from 'react'
import { useTypedTrack } from '../analytics/useTypedTrack'

export const TypedExample: React.FC = () => {
  const { trackEvent } = useTypedTrack()

  const handleClick = () => {
    // Здесь мы создаем строго типизированное событие
    trackEvent({
      name: 'Product Added To Cart',
      properties: {
        productId: '123',
        price: 42,
      },
    })
  }

  return (
    <button onClick={handleClick}>
      Добавить с типами
    </button>
  )
}

Как видите, этот код выполняет:

  • статическую проверку свойств события;
  • защиту от опечаток в имени события;
  • улучшение документации по событиям прямо в коде.

Состояние загрузки и ошибки инициализации Segment

Иногда Segment может загружаться не сразу:

  • медленный интернет;
  • блокировщики рекламы;
  • проблемы с конфигурацией.

При использовании hooks-segment часто доступен статус:

  • isReady или loaded;
  • возможно, информация об ошибке.

Пример условного API:

// src/analytics/useSafeSegment.ts
import { useSegment } from 'hooks-segment'

export const useSafeSegment = () => {
  const { analytics, isReady, error } = useSegment()

  // Здесь мы возвращаем объект, который можно безопасно использовать в компонентах
  return {
    analytics,
    isReady,
    error,
  }
}

Использование:

// src/components/SafeButton.tsx
import React from 'react'
import { useSafeSegment } from '../analytics/useSafeSegment'

export const SafeButton: React.FC = () => {
  const { analytics, isReady } = useSafeSegment()

  const handleClick = () => {
    // Здесь проверяем, готов ли Segment, прежде чем отправлять событие
    if (!isReady) return

    analytics.track('Button Clicked', { label: 'SafeButton' })
  }

  return (
    <button onClick={handleClick} disabled={!isReady}>
      Клик с безопасной аналитикой
    </button>
  )
}

Так вы избегаете ошибок, когда analytics еще не инициализирован.


SSR и Next.js особенности

В проектах на Next.js (особенно с SSR) важно учитывать:

  • код Segment должен выполняться только в браузере;
  • на сервере глобальный объект window недоступен.

Типичный подход:

  1. Инициализировать Segment только после монтирования на клиенте.
  2. Отключать трекинг на сервере.

Покажу упрощенный пример:

// src/analytics/SegmentProvider.tsx
import React, { useEffect, useState } from 'react'
import { SegmentProvider as BaseSegmentProvider } from 'hooks-segment'

const writeKey = process.env.NEXT_PUBLIC_SEGMENT_WRITE_KEY as string

export const SegmentProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [isClient, setIsClient] = useState(false)

  useEffect(() => {
    // Здесь мы отмечаем, что код выполняется в браузере
    setIsClient(true)
  }, [])

  if (!isClient) {
    // На сервере и до монтирования мы не инициализируем Segment
    return <>{children}</>
  }

  return (
    <BaseSegmentProvider writeKey={writeKey}>
      {children}
    </BaseSegmentProvider>
  )
}

Такой подход позволяет:

  • избежать ошибок доступа к window на сервере;
  • подключить Segment только там, где он действительно нужен — в браузере.

Отключение трекинга в режиме разработки и для сотрудников

Частая задача — не портить аналитику:

  • локальными запусками;
  • тестированием;
  • действиями сотрудников компании.

hooks-segment обычно позволяет отключить или переопределить поведение при инициализации.

Один из подходов:

// src/analytics/SegmentProvider.tsx
import React from 'react'
import { SegmentProvider as BaseSegmentProvider } from 'hooks-segment'

const writeKey = process.env.REACT_APP_SEGMENT_WRITE_KEY as string

const isTrackingEnabled = process.env.NODE_ENV === 'production'

export const SegmentProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  if (!isTrackingEnabled) {
    // Если трекинг выключен, можно вернуть провайдер-заглушку
    // или просто не инициализировать реальный Segment
    return <>{children}</>
  }

  return (
    <BaseSegmentProvider writeKey={writeKey}>
      {children}
    </BaseSegmentProvider>
  )
}

Дополнительно:

  • можно проверять email пользователя и не отслеживать внутренних сотрудников;
  • можно передавать флаг optOut в Segment и использовать встроенные механизмы.

Заключение

hooks-segment делает интеграцию Segment с React-приложениями более предсказуемой и удобной. Вместо прямого обращения к глобальному analytics вы работаете с хуками и контекстом, что:

  • упрощает типизацию и тестирование;
  • позволяет централизовать логику аналитики;
  • лучше вписывается в архитектуру современных фронтенд-приложений.

Основные шаги работы с Сегмент hooks:

  1. Установить библиотеку и обернуть приложение в SegmentProvider.
  2. Использовать общий хук (useSegment) для доступа к методам track, identify, page, group, alias.
  3. Построить над этим доменный слой: useShopAnalytics, useUserAnalytics и другие.
  4. Настроить автоматическое отслеживание страниц и важных пользовательских действий.
  5. Учитывать особенности SSR и окружения (отключение трекинга в dev, обработка ошибок загрузки).

Если вы будете относиться к аналитике как к отдельному слою приложения, а не к случайным вызовам в компонентах, hooks-segment как раз поможет организовать этот слой аккуратно и прозрачно.


Частозадаваемые технические вопросы и ответы

Как замокать hooks-segment в unit-тестах React-компонентов

Обычно достаточно замокать хук или провайдера. Пример с Jest:

// Здесь мы замещаем реальную библиотеку заглушкой
jest.mock('hooks-segment', () => ({
  useSegment: () => ({
    track: jest.fn(),
    identify: jest.fn(),
    page: jest.fn(),
  }),
}))

Дальше вы рендерите компонент и проверяете, вызывался ли track с нужными аргументами. Важно не забыть сбрасывать моки между тестами.

Как отложить инициализацию Segment до согласия с cookies

Можно хранить состояние согласия в приложении и инициализировать SegmentProvider только после согласия:

// Если пользователь не дал согласие - не рендерим провайдер
return hasConsent ? (
  <SegmentProvider writeKey={writeKey}>{children}</SegmentProvider>
) : (
  <>{children}</>
)

Пока согласия нет, события не отправляются. После согласия вы можете один раз инициализировать Segment.

Что делать, если браузер блокирует Segment-скрипты

В таких случаях analytics может не инициализироваться. Нужно:

  1. Обрабатывать состояние isReady или аналогичный флаг из hooks-segment.
  2. Не вызывать методы трекинга до готовности.
  3. Логировать ошибки в fallback-систему (например, Sentry), если SDK сообщает об ошибке.

Так вы избежите падений приложения и сможете видеть долю пользователей с блокировщиками.

Как добавить кастомный транспорт для отправки данных (например через proxy)

Если библиотека hooks-segment позволяет передавать options при инициализации, используйте их:

<SegmentProvider
  writeKey={writeKey}
  options={{
    apiHost: 'https://analytics-proxy.mycompany.com',
  }}
>
  {children}
</SegmentProvider>

Дальше прокси пересылает запросы в реальный Segment. Это помогает обойти ограничения сетевой инфраструктуры.

Как мигрировать с прямого использования window.analytics на hooks-segment

Шаги:

  1. Ввести SegmentProvider и подключить его в корне.
  2. Написать обертку useAnalytics, которая сначала внутри использует window.analytics.
  3. Постепенно заменить прямые обращения к window.analytics на useAnalytics.
  4. После этого переключить реализацию useAnalytics на hooks-segment.
  5. Удалить старый код, использующий глобальный объект.

Так вы переходите к hooks-segment без одномоментного переписывания всего проекта.

Стрелочка влевоСегмент constants в Go - устройство constants-segment и практическое использованиеСегмент components - как использовать components-segment в интерфейсных проектахСтрелочка вправо

Все гайды по Feature-sliced_design

Открыть базу знаний

Отправить комментарий