Contentful Personalization & Analytics
    Preparing search index...

    Client for sending analytics and insights events to the Ninetailed Insights API.

    This client is optimized for sending batched events, optionally using a custom beacon-like handler when available.

    const insightsClient = new InsightsApiClient({
    clientId: 'org-id',
    environment: 'main',
    })

    await insightsClient.sendBatchEvents([
    {
    profile: { id: 'profile-123', ... },
    events: [
    {
    type: 'track',
    event: 'button_clicked',
    properties: { id: 'primary-cta' },
    },
    ],
    }
    ])

    Extends ApiClientBase.

    Hierarchy

    • ApiClientBase
      • InsightsApiClient
    Index

    Constructors

    Properties

    baseUrl: string

    Base URL used for Insights API requests.

    clientId: string

    Client identifier used for authentication or tracking.

    environment: string

    Contentful environment associated with this client.

    Protected fetch method used by the client to perform HTTP requests.

    name: string

    Name of the API client, used in log messages and as the apiName for fetch.

    Methods

    • Logs errors that occur during API requests with standardized messages.

      Parameters

      • error: unknown

        The error thrown by the underlying operation.

      • options: { requestName: string }

        Additional metadata about the request.

        • requestName: string

          Human-readable name of the request operation.

      Returns void

      Abort errors are logged at warn level and other errors at error level. The log message includes the client name for better debugging context.

    • Sends batches of insights events to the Ninetailed Insights API.

      Parameters

      • batches: {
            events: (
                | {
                    channel: "mobile"
                    | "server"
                    | "web";
                    componentId: string;
                    componentType: "Entry" | "Variable";
                    context: {
                        app?: { name: string; version: string };
                        campaign: {
                            content?: string;
                            medium?: string;
                            name?: string;
                            source?: string;
                            term?: string;
                        };
                        gdpr: { isConsentGiven: boolean };
                        library: { name: string; version: string };
                        locale: string;
                        location?: {
                            city?: string;
                            continent?: string;
                            coordinates?: { latitude: number; longitude: number };
                            country?: string;
                            countryCode?: string;
                            postalCode?: string;
                            region?: string;
                            regionCode?: string;
                            timezone?: string;
                        };
                        page?: {
                            path: string;
                            query: Record<string, string>;
                            referrer: string;
                            search: string;
                            title?: string;
                            url: string;
                            [key: string]: JSONType;
                        };
                        screen?: { name: string; [key: string]: JSONType };
                        userAgent?: string;
                    };
                    experienceId?: string;
                    messageId: string;
                    originalTimestamp: string;
                    sentAt: string;
                    timestamp: string;
                    type: "component";
                    userId?: string;
                    variantIndex: number;
                    viewDurationMs?: number;
                    viewId?: string;
                }
                | {
                    channel: "mobile"
                    | "server"
                    | "web";
                    componentId: string;
                    componentType: "Entry" | "Variable";
                    context: {
                        app?: { name: string; version: string };
                        campaign: {
                            content?: string;
                            medium?: string;
                            name?: string;
                            source?: string;
                            term?: string;
                        };
                        gdpr: { isConsentGiven: boolean };
                        library: { name: string; version: string };
                        locale: string;
                        location?: {
                            city?: string;
                            continent?: string;
                            coordinates?: { latitude: number; longitude: number };
                            country?: string;
                            countryCode?: string;
                            postalCode?: string;
                            region?: string;
                            regionCode?: string;
                            timezone?: string;
                        };
                        page?: {
                            path: string;
                            query: Record<string, string>;
                            referrer: string;
                            search: string;
                            title?: string;
                            url: string;
                            [key: string]: JSONType;
                        };
                        screen?: { name: string; [key: string]: JSONType };
                        userAgent?: string;
                    };
                    experienceId?: string;
                    messageId: string;
                    originalTimestamp: string;
                    sentAt: string;
                    timestamp: string;
                    type: "component_click";
                    userId?: string;
                    variantIndex: number;
                }
                | {
                    channel: "mobile"
                    | "server"
                    | "web";
                    componentId: string;
                    componentType: "Entry" | "Variable";
                    context: {
                        app?: { name: string; version: string };
                        campaign: {
                            content?: string;
                            medium?: string;
                            name?: string;
                            source?: string;
                            term?: string;
                        };
                        gdpr: { isConsentGiven: boolean };
                        library: { name: string; version: string };
                        locale: string;
                        location?: {
                            city?: string;
                            continent?: string;
                            coordinates?: { latitude: number; longitude: number };
                            country?: string;
                            countryCode?: string;
                            postalCode?: string;
                            region?: string;
                            regionCode?: string;
                            timezone?: string;
                        };
                        page?: {
                            path: string;
                            query: Record<string, string>;
                            referrer: string;
                            search: string;
                            title?: string;
                            url: string;
                            [key: string]: JSONType;
                        };
                        screen?: { name: string; [key: string]: JSONType };
                        userAgent?: string;
                    };
                    experienceId?: string;
                    hoverDurationMs: number;
                    hoverId: string;
                    messageId: string;
                    originalTimestamp: string;
                    sentAt: string;
                    timestamp: string;
                    type: "component_hover";
                    userId?: string;
                    variantIndex: number;
                }
            )[];
            profile: { id: string; [key: string]: JSONType };
        }[]

        Array of event batches to send.

        • events: (
              | {
                  channel: "mobile"
                  | "server"
                  | "web";
                  componentId: string;
                  componentType: "Entry" | "Variable";
                  context: {
                      app?: { name: string; version: string };
                      campaign: {
                          content?: string;
                          medium?: string;
                          name?: string;
                          source?: string;
                          term?: string;
                      };
                      gdpr: { isConsentGiven: boolean };
                      library: { name: string; version: string };
                      locale: string;
                      location?: {
                          city?: string;
                          continent?: string;
                          coordinates?: { latitude: number; longitude: number };
                          country?: string;
                          countryCode?: string;
                          postalCode?: string;
                          region?: string;
                          regionCode?: string;
                          timezone?: string;
                      };
                      page?: {
                          path: string;
                          query: Record<string, string>;
                          referrer: string;
                          search: string;
                          title?: string;
                          url: string;
                          [key: string]: JSONType;
                      };
                      screen?: { name: string; [key: string]: JSONType };
                      userAgent?: string;
                  };
                  experienceId?: string;
                  messageId: string;
                  originalTimestamp: string;
                  sentAt: string;
                  timestamp: string;
                  type: "component";
                  userId?: string;
                  variantIndex: number;
                  viewDurationMs?: number;
                  viewId?: string;
              }
              | {
                  channel: "mobile"
                  | "server"
                  | "web";
                  componentId: string;
                  componentType: "Entry" | "Variable";
                  context: {
                      app?: { name: string; version: string };
                      campaign: {
                          content?: string;
                          medium?: string;
                          name?: string;
                          source?: string;
                          term?: string;
                      };
                      gdpr: { isConsentGiven: boolean };
                      library: { name: string; version: string };
                      locale: string;
                      location?: {
                          city?: string;
                          continent?: string;
                          coordinates?: { latitude: number; longitude: number };
                          country?: string;
                          countryCode?: string;
                          postalCode?: string;
                          region?: string;
                          regionCode?: string;
                          timezone?: string;
                      };
                      page?: {
                          path: string;
                          query: Record<string, string>;
                          referrer: string;
                          search: string;
                          title?: string;
                          url: string;
                          [key: string]: JSONType;
                      };
                      screen?: { name: string; [key: string]: JSONType };
                      userAgent?: string;
                  };
                  experienceId?: string;
                  messageId: string;
                  originalTimestamp: string;
                  sentAt: string;
                  timestamp: string;
                  type: "component_click";
                  userId?: string;
                  variantIndex: number;
              }
              | {
                  channel: "mobile"
                  | "server"
                  | "web";
                  componentId: string;
                  componentType: "Entry" | "Variable";
                  context: {
                      app?: { name: string; version: string };
                      campaign: {
                          content?: string;
                          medium?: string;
                          name?: string;
                          source?: string;
                          term?: string;
                      };
                      gdpr: { isConsentGiven: boolean };
                      library: { name: string; version: string };
                      locale: string;
                      location?: {
                          city?: string;
                          continent?: string;
                          coordinates?: { latitude: number; longitude: number };
                          country?: string;
                          countryCode?: string;
                          postalCode?: string;
                          region?: string;
                          regionCode?: string;
                          timezone?: string;
                      };
                      page?: {
                          path: string;
                          query: Record<string, string>;
                          referrer: string;
                          search: string;
                          title?: string;
                          url: string;
                          [key: string]: JSONType;
                      };
                      screen?: { name: string; [key: string]: JSONType };
                      userAgent?: string;
                  };
                  experienceId?: string;
                  hoverDurationMs: number;
                  hoverId: string;
                  messageId: string;
                  originalTimestamp: string;
                  sentAt: string;
                  timestamp: string;
                  type: "component_hover";
                  userId?: string;
                  variantIndex: number;
              }
          )[]

          Insights events that should be recorded for this profile.

        • profile: { id: string; [key: string]: JSONType }

          Partial profile information used to associate events with a user.

          • id: string

            Identifier of the profile.

            Used to associate events with an existing profile.

      • options: InsightsApiClientRequestOptions = {}

        Optional request options, including a per-call beaconHandler.

      Returns Promise<boolean>

      true when the event batch is successfully queued by the beacon handler or a direct request is successfully sent, false otherwise.

      If a beaconHandler is provided (either in the method call or in the client configuration) it will be invoked first. When the handler returns true, the events are considered successfully queued and no network request is made by this method.

      If the handler is missing or returns false, the events are emitted immediately via fetch.

      const success = await insightsClient.sendBatchEvents(batches)
      
      // Override beaconHandler for a single call
      const success = await insightsClient.sendBatchEvents(batches, {
      beaconHandler: (url, data) => {
      return navigator.sendBeacon(url.toString(), JSON.stringify(data))
      },
      })