TourKit
@tour-kit/analyticsHooks

Analytics Hooks

useAnalytics hook: access the analytics tracker to send custom events and track tour interactions in React components

Overview

User Tour Kit provides two hooks for accessing the analytics tracker in your components:

  • useAnalytics() - Throws error if not in provider (strict)
  • useAnalyticsOptional() - Returns null if not in provider (lenient)

useAnalytics

Access the analytics tracker with strict provider enforcement.

Usage

import { useAnalytics } from '@tour-kit/analytics'

function MyComponent() {
  const analytics = useAnalytics()

  const handleClick = () => {
    analytics.track('feature_used', {
      tourId: 'feature-demo',
      metadata: { feature: 'export-data' }
    })
  }

  return <button onClick={handleClick}>Export</button>
}

Error Handling

This hook throws an error if used outside an AnalyticsProvider:

// This will throw an error
function BadComponent() {
  const analytics = useAnalytics() // Error: useAnalytics must be used within AnalyticsProvider
  return <div>...</div>
}

Always ensure components using useAnalytics are rendered within an AnalyticsProvider.

When to Use

Use useAnalytics() when:

  • Analytics are required for the component to function
  • You want to catch configuration errors early
  • The component is always rendered within a provider

useAnalyticsOptional

Access the analytics tracker with optional provider support.

Usage

import { useAnalyticsOptional } from '@tour-kit/analytics'

function OptionalTrackingComponent() {
  const analytics = useAnalyticsOptional()

  const handleClick = () => {
    // Only track if analytics is available
    analytics?.track('button_clicked', {
      tourId: 'optional-feature',
      metadata: { source: 'sidebar' }
    })
  }

  return <button onClick={handleClick}>Click Me</button>
}

Null Safety

This hook returns null when not in a provider:

function SafeComponent() {
  const analytics = useAnalyticsOptional()

  if (!analytics) {
    // Analytics not configured - component still works
    return <div>No tracking</div>
  }

  return <div>Tracking enabled</div>
}

When to Use

Use useAnalyticsOptional() when:

  • Analytics are nice-to-have but not required
  • The component should work without a provider
  • You're building reusable components for multiple apps

Tracking Custom Events

Feature Usage

Track when users interact with specific features:

import { useAnalytics } from '@tour-kit/analytics'

function AdvancedSearch() {
  const analytics = useAnalytics()

  const handleSearch = (query: string, filters: string[]) => {
    analytics.track('feature_used', {
      tourId: 'advanced-search',
      metadata: {
        query_length: query.length,
        filter_count: filters.length,
        filters: filters.join(',')
      }
    })
  }

  return <SearchForm onSubmit={handleSearch} />
}

Step Interactions

Track user interactions within tour steps:

import { useAnalytics } from '@tour-kit/analytics'
import { useTour } from '@tour-kit/core'

function InteractiveTourStep() {
  const analytics = useAnalytics()
  const { tourId, currentStep } = useTour()

  const handleVideoPlay = () => {
    analytics.stepInteraction(
      tourId,
      currentStep.id,
      'video_played',
      { video_duration: 120 }
    )
  }

  return (
    <div>
      <video onPlay={handleVideoPlay}>...</video>
    </div>
  )
}

User Identification

Identify users after authentication:

'use client'

import { useAnalytics } from '@tour-kit/analytics'
import { useEffect } from 'react'

function UserIdentifier({ user }) {
  const analytics = useAnalytics()

  useEffect(() => {
    if (user) {
      analytics.identify(user.id, {
        email: user.email,
        plan: user.plan,
        signup_date: user.createdAt
      })
    }
  }, [user, analytics])

  return null
}

TourAnalytics Methods

The analytics object returned by both hooks provides these methods:

Identification

// Identify a user
analytics.identify(userId: string, properties?: Record<string, unknown>)

Raw Event Tracking

// Track any event type
analytics.track(
  eventName: TourEventName,
  data: TourEventData
)

Tour Lifecycle

// Track tour start
analytics.tourStarted(tourId: string, totalSteps: number, metadata?: Record<string, unknown>)

// Track tour completion
analytics.tourCompleted(tourId: string, metadata?: Record<string, unknown>)

// Track tour skip
analytics.tourSkipped(
  tourId: string,
  stepIndex: number,
  stepId?: string,
  metadata?: Record<string, unknown>
)

// Track tour abandonment
analytics.tourAbandoned(
  tourId: string,
  stepIndex: number,
  stepId?: string,
  metadata?: Record<string, unknown>
)

Step Lifecycle

// Track step view
analytics.stepViewed(
  tourId: string,
  stepId: string,
  stepIndex: number,
  totalSteps: number,
  metadata?: Record<string, unknown>
)

// Track step completion
analytics.stepCompleted(
  tourId: string,
  stepId: string,
  stepIndex: number,
  metadata?: Record<string, unknown>
)

// Track step skip
analytics.stepSkipped(
  tourId: string,
  stepId: string,
  stepIndex: number,
  metadata?: Record<string, unknown>
)

// Track step interaction
analytics.stepInteraction(
  tourId: string,
  stepId: string,
  interactionType: string,
  metadata?: Record<string, unknown>
)

Hint Tracking

// Track hint shown
analytics.hintShown(hintId: string, metadata?: Record<string, unknown>)

// Track hint dismissed
analytics.hintDismissed(hintId: string, metadata?: Record<string, unknown>)

// Track hint clicked
analytics.hintClicked(hintId: string, metadata?: Record<string, unknown>)

Utility Methods

// Flush queued events immediately
await analytics.flush()

// Clean up and destroy tracker
analytics.destroy()

Type Safety

Both hooks return a fully typed TourAnalytics instance:

import { useAnalytics } from '@tour-kit/analytics'
import type { TourAnalytics } from '@tour-kit/analytics'

function TypedComponent() {
  const analytics: TourAnalytics = useAnalytics()

  // Full TypeScript autocomplete and type checking
  analytics.track('tour_started', {
    tourId: 'onboarding',
    totalSteps: 5
  })

  return <div>...</div>
}

Combining with Tour Hooks

Use analytics hooks alongside tour hooks for rich tracking:

import { useAnalytics } from '@tour-kit/analytics'
import { useTour } from '@tour-kit/core'

function TourWithAnalytics() {
  const analytics = useAnalytics()
  const { tourId, currentStep, next, skip } = useTour()

  const handleNext = () => {
    analytics.stepCompleted(tourId, currentStep.id, currentStep.index)
    next()
  }

  const handleSkip = () => {
    analytics.tourSkipped(tourId, currentStep.index, currentStep.id)
    skip()
  }

  return (
    <div>
      <button onClick={handleNext}>Next</button>
      <button onClick={handleSkip}>Skip Tour</button>
    </div>
  )
}

On this page