UNPKG

@amplitude/engagement-browser

Version:

Official Amplitude SDK for Web

961 lines (894 loc) 29 kB
import type { Plugin, Logger as ILogger, Event } from '@amplitude/analytics-types'; /** * Configuration options for initializing the Engagement SDK. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#initialize-the-sdk} */ export type InitOptions = { /** * Sets the Amplitude server zone. Set this to EU for Amplitude projects created in EU data center. * @default 'US' */ serverZone?: 'EU' | 'US' | 'local'; /** * Sets a custom server URL for API requests. Useful for proxy setups. * @default 'https://gs.amplitude.com' (US) or 'https://gs.eu.amplitude.com' (EU) * @see {@link https://amplitude.com/docs/guides-and-surveys/proxy} */ serverUrl?: string; /** * Sets a custom URL for chat functionality. */ chatUrl?: string; /** * Sets a custom URL for proxying guide and survey images. Useful for proxy setups when images are blocked. * @default 'https://engagement-static.amplitude.com' (US) or 'https://engagement-static.eu.amplitude.com' (EU) * @see {@link https://amplitude.com/docs/guides-and-surveys/proxy} */ mediaUrl?: string; /** * Sets the locale for localization. * @default undefined (uses default language) * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#localization} */ locale?: string; /** * Sets a custom CDN URL for static assets. Useful for proxy setups. * @default 'https://cdn.amplitude.com' (US) or 'https://cdn.eu.amplitude.com' (EU) * @see {@link https://amplitude.com/docs/guides-and-surveys/proxy} */ cdnUrl?: string; /** * Uses the `amplitudeengagement.com` domain for all API, chat, media, and CDN requests * instead of the default `amplitude.com` domain. Only supported in prod US and prod EU. * Explicit `serverUrl`, `chatUrl`, `mediaUrl`, or `cdnUrl` values take precedence. * @default false */ useEngagementDomain?: boolean; options?: { /** * Sets a custom logging provider class. * @see {@link https://github.com/amplitude/Amplitude-TypeScript/blob/main/packages/analytics-types/src/logger.ts} */ logger?: ILogger; /** * Sets the log level. * @default LogLevel.Warn */ logLevel?: number; /** * Enables code splitting for faster initial load times. * @default true */ splitting?: boolean; /** * Persists Resource Center state across sessions. * @default false */ persistResourceCenter?: boolean; /** * Enables headless mode for custom rendering. * @default false */ headless?: boolean; /** * Renders CSS styles directly in the DOM instead of using CSS-in-JS. * @default false */ renderCssInDom?: boolean; /** * Custom DOM element ID where the SDK should mount its container. */ mountElementId?: string; [key: string]: any; }; /** * Sets a nonce value for Content Security Policy (CSP) compliance. * This allows inline styles required by Guides and Surveys to be executed when CSP is enabled. * @default undefined */ nonce?: string; }; /** * User properties object containing key-value pairs. * These properties can be used as variables inside guides and surveys content with the `{{ property.propertyName }}` syntax. */ export type UserProperties = Record<string, any>; /** * End user identification and properties. * At least one of `user_id` or `device_id` must be provided. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#boot} */ export type EndUser = { /** * Unique user identifier. At least one of user_id or device_id is required. */ user_id?: string; /** * Unique device identifier. At least one of user_id or device_id is required. */ device_id?: string; /** * User properties for personalization and targeting. * These can be referenced in guide and survey content using `{{ properties.propertyName }}`. */ user_properties?: UserProperties; /** * Function to retrieve the current session ID. */ getSessionId?: () => number | undefined; }; /** * Integration for forwarding SDK events to third-party analytics providers. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#other-amplitude-sdks-and-third-party-analytics-providers} */ export type Integration = { /** * Function called when the SDK tracks an event. */ track?: (event: Event) => void; }; /** * Options for booting the SDK and identifying the end user. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#boot} */ export type BootOptions = { /** * End user identification. Can be: * - An EndUser object with user_id and/or device_id * - A function that returns an EndUser object * - A string representing the user_id * * At least one of user_id or device_id must be provided. */ user: EndUser | (() => EndUser) | string; /** * Array of integrations to forward SDK events to third-party analytics providers. */ integrations?: Array<Integration>; /** * Auto-refresh interval in seconds. If not specified, 0, or negative, auto-refresh is disabled. * When enabled, the SDK will automatically refresh (re-fetch targeting, user interaction state, and reload guides and surveys configuration) * at this interval. Must be greater than 60 seconds. * * @example * // Refresh every hour * autoRefreshIntervalSeconds: 3600 * * // Refresh every 30 minutes * autoRefreshIntervalSeconds: 1800 */ autoRefreshIntervalSeconds?: number; }; /** * Session property value types. * Session properties provide an additional way to restrict when guides and surveys are triggered. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#set-session-properties} */ export type SessionPropertyValue = string | number | boolean | null; /** * Session property key. */ export type SessionPropertyKey = string; /** * Tag filter for content targeting. * Supports filtering by tags with nested AND/OR logic. * Used for both Assistant chat and Resource Center content filtering. * * @example * ```typescript * // Filter Assistant to content with specific tags * window.engagement.assistant.setAssistantFilter({ tags: ['billing'] }); * * // Filter Resource Center with complex AND/OR logic * window.engagement.setResourceCenterFilter({ * and: [ * { tags: ['billing', 'payments'] }, * { tags: ['enterprise'] } * ] * }); * ``` */ export type TagFilter = { tags: string[] } | { and: TagFilter[] } | { or: TagFilter[] }; /** * Survey response value types. * Represents a survey response with metadata about the response type and values. */ export type SurveyResponse = | { blockId: string; type: 'number' | 'nps'; value: number; stringResponse: string | undefined; max: number } | { blockId: string; type: 'string'; value: number | string; stringResponse: string; otherText?: string } | { blockId: string; type: 'string'; value: number[]; stringResponse: string[]; otherText?: string }; /** * Callback function type */ export type PublicCallbackFunction = (...args: any[]) => void; /** * Guide and Survey service namespace. * Access via `window.engagement.gs`. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk} */ export interface GuidesAndSurveysService { /** * Resets a guide or survey to a specific step. If no step is provided, resets to the initial step. * If the guide or survey is currently active, it will become inactive. * * @param key - The flag key of the guide or survey to reset * @param step - Optional. The zero-based step index to reset to * * @example * ```typescript * // Reset to beginning * window.engagement.gs.reset('my-guide-key'); * * // Reset to specific step * window.engagement.gs.reset('my-guide-key', 2); * ``` */ reset(key: string, step?: number): void; /** * Returns all guides and surveys with their lifecycle state. * Useful for headless implementations or custom UI rendering. * * @param filterOptions - Optional filters to apply * @param filterOptions.onlyEligible - Only return guides/surveys that pass all eligibility checks * @param filterOptions.variantIds - Only return guides/surveys with these variant IDs * @param skipChecks - Array of check types to skip during evaluation * * @returns Array of guides and surveys with their lifecycle state * * @example * ```typescript * // Get all eligible guides * const eligible = window.engagement.gs.getAllGuidesAndSurveys({ onlyEligible: true }); * * // Get specific guides by variant ID * const specific = window.engagement.gs.getAllGuidesAndSurveys({ variantIds: [123, 456] }); * * // Skip certain checks for testing * const all = window.engagement.gs.getAllGuidesAndSurveys({}, ['userTargeting', 'limits']); * ``` */ getAllGuidesAndSurveys( filterOptions?: { onlyEligible?: boolean; variantIds?: Array<number>; }, skipChecks?: Array<'userTargeting' | 'sessionProperties' | 'limits' | 'page' | 'snooze'>, ): Array<any>; /** * Returns a preview of a guide or survey by variant ID. * Used primarily for preview mode in the Amplitude dashboard. * * @param variantId - The variant ID of the guide or survey * @returns Promise resolving to the guide or survey with lifecycle state */ getPreviewGuideOrSurvey(variantId: number): Promise<any>; /** * Returns a list of currently active and/or visible guides or surveys. * * @returns Array of active/visible guides with their current state * * @example * ```typescript * const active = window.engagement.gs.list(); * console.log(active); // [{ id: 123, key: 'my-guide', step: 1, title: 'Onboarding', status: 'visible' }] * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#list} */ list(): Array<{ /** Variant ID of the guide or survey */ id: number; /** Flag key of the guide or survey */ key: string; /** Current step index (zero-based) */ step?: number; /** Title of the guide or survey */ title: string; /** Status: 'visible' if currently shown, 'active' if running but not visible */ status: 'visible' | 'active'; }>; /** * Manually trigger a guide or survey by its flag key. * * @param flagKey - The flag key of the guide or survey to show * @param step - Optional. The zero-based step index to start at (default: 0) * * @example * ```typescript * // Show from beginning * window.engagement.gs.show('my-guide-key'); * * // Show starting at step 2 * window.engagement.gs.show('my-guide-key', 2); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#show} */ show(flagKey: string, step?: number): void; /** * Force close all active guides and surveys. * Analytics events will not be sent for guides or surveys that are closed this way. * * @example * ```typescript * window.engagement.gs.closeAll(); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#close-all} */ closeAll(): void; } /** * Resource Center service namespace. * Access via `window.engagement.rc`. * * @see {@link https://amplitude.com/docs/guides-and-surveys/resource-center} */ export interface ResourceCenterService { /** * Opens the Resource Center widget. * * @example * ```typescript * window.engagement.rc.open(); * ``` */ open(): void; /** * Closes the Resource Center widget. * * @example * ```typescript * window.engagement.rc.close(); * ``` */ close(): void; /** * Toggles the Resource Center widget visibility. * * @example * ```typescript * window.engagement.rc.toggle(); * ``` */ toggle(): void; } /** * Assistant service namespace. * Access via `window.engagement.assistant`. */ export interface AssistantService { /** * Opens the Assistant widget. * * By default, Assistant opens to the Resource Center page. To open directly to chat, * pass `{ initialPage: 'chat' }`. * * @param options - Optional configuration for the initial page * * @example * ```typescript * // Open to Resource Center (default) * window.engagement.assistant.show(); * * // Open directly to chat * window.engagement.assistant.show({ initialPage: 'chat' }); * ``` */ show(options?: { initialPage?: 'chat' | 'resourceCenter' }): void; /** * Sets a filter to restrict Assistant chat content by tags. * Applies only to Assistant chat responses and tool results. * * @param filter - Tag filter object or null to clear the filter * * @example * ```typescript * // Filter to content tagged "billing" * window.engagement.assistant.setAssistantFilter({ * tags: ["billing"] * }); * * // Complex filter with AND/OR logic * window.engagement.assistant.setAssistantFilter({ * and: [ * { tags: ["billing", "payments"] }, * { tags: ["enterprise"] } * ] * }); * * // Clear the filter * window.engagement.assistant.setAssistantFilter(null); * ``` */ setAssistantFilter(filter: TagFilter | null): void; } /** * Main Engagement SDK interface available on `window.engagement`. * * The SDK enables you to deploy Guides and Surveys on your website or application. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk} * * @example * ```typescript * // Initialize the SDK * window.engagement.init('YOUR_API_KEY', { serverZone: 'US' }); * * // Boot with a user * await window.engagement.boot({ user: { user_id: 'user-123' } }); * * // Show a guide * window.engagement.gs.show('my-guide-key'); * ``` */ export interface EngagementSDK { /** * Guides and Surveys service namespace. * Provides methods to manage and interact with guides and surveys. * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk} */ gs: GuidesAndSurveysService; /** * Resource Center service namespace. * Provides methods to control the Resource Center widget. * * @see {@link https://amplitude.com/docs/guides-and-surveys/resource-center} */ rc: ResourceCenterService; /** * Initializes the Engagement SDK. This will usually not be necessary as it happens automatically * when you do `amplitude.add(engagement.plugin())`. * * **Note:** When using the plugin with `amplitude.add(engagementPlugin())`, don't call `init()` or `boot()`. * The plugin handles initialization automatically. * * Only call `init()` and `boot()` manually if you need to integrate with a third-party analytics provider. * * @param apiKey - Amplitude API Key. Must be the same key used for your Analytics SDK to avoid data mismatches. * @param initOptions - Optional configuration options * * @example * ```typescript * // Basic initialization * window.engagement.init('YOUR_API_KEY', { * serverZone: 'US', * logLevel: LogLevel.Warn * }); * * // Initialization with proxy * window.engagement.init('YOUR_API_KEY', { * serverUrl: 'https://your-proxy.cloudfront.net', * cdnUrl: 'https://your-proxy.cloudfront.net', * mediaUrl: 'https://your-proxy.cloudfront.net', * }); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#initialize-the-sdk} */ init(apiKey: string, initOptions?: InitOptions): void; /** * Returns an Amplitude plugin for the Engagement SDK. * Use this when integrating with Amplitude Browser SDK 2.0. * * **Recommended approach:** This is the simplest way to use Guides and Surveys with Amplitude Analytics. * * @param options - Optional configuration options * @returns Amplitude Plugin object * * @example * ```typescript * import * as amplitude from '@amplitude/analytics-browser'; * import { plugin as engagementPlugin } from '@amplitude/engagement-browser'; * * amplitude.init('YOUR_API_KEY'); * amplitude.add(engagementPlugin()); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#amplitude-browser-sdk-2} */ plugin(options?: InitOptions): Plugin; /** * Make Guides and Surveys available to the user. They will not be available before `.boot()` is called, * even if the snippet has been run on the page. * * **Important:** The user must specify at least a `user_id` or `device_id`. * * **Note:** When using the plugin approach (`amplitude.add(engagementPlugin())`), don't call `boot()`. * The plugin handles this automatically. * * @param options - Boot options including user identification * @returns Promise that resolves when boot is complete * * @example * ```typescript * // Boot with user ID * await window.engagement.boot({ user: { user_id: 'user-123' } }); * * // Boot with device ID and properties * await window.engagement.boot({ * user: { * device_id: 'device-456', * user_properties: { plan: 'premium' } * } * }); * * // Boot with user function (for dynamic values) * await window.engagement.boot({ * user: () => ({ * user_id: getCurrentUserId(), * user_properties: getCurrentUserProperties() * }) * }); * * // Boot with auto-refresh every hour * await window.engagement.boot({ * user: { user_id: 'user-123' }, * autoRefreshIntervalSeconds: 3600 * }); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#boot} */ boot(options: BootOptions): Promise<void>; /** * Shuts down the SDK and clears the current user session. * Call this when a user logs out or you need to switch users. * * After calling `shutdown()`, you can call `boot()` again with a different user. * * @example * ```typescript * // User logs out * window.engagement.shutdown(); * * // Later, when a new user logs in * await window.engagement.boot({ user: { user_id: 'new-user-456' } }); * ``` */ shutdown(): void; /** * Refresh the SDK state by re-fetching decide data, end user store, and reloading nudges. * Useful when you want to manually check for new guides or surveys. * * The refresh will be skipped if any guides or surveys are currently visible to avoid closing them. * * @returns Promise that resolves when refresh is complete * * @example * ```typescript * // Manually refresh to check for new content * await window.engagement.refresh(); * ``` */ refresh(): Promise<void>; /** * Forward third-party Analytics events to the Guides and Surveys SDK to trigger guides and surveys * that use the "On event tracked" trigger. * * @param event - An Amplitude event object or event name string * * @example * ```typescript * // Forward event by name * window.engagement.forwardEvent('button_clicked'); * * // Forward event with properties * window.engagement.forwardEvent({ * event_type: 'purchase_completed', * event_properties: { amount: 99.99, currency: 'USD' } * }); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#forward-event} */ forwardEvent(event: Event | string): void; /** * Add an integration to track events generated by the SDK. * You may also pass integrations to `boot()` directly. * * This allows you to forward SDK-generated events to third-party analytics providers. * * @param integration - The integration object with a track function * * @example * ```typescript * window.engagement.addIntegration({ * track: (event) => { * // Forward to your analytics provider * mixpanel.track(event.event_type, event.event_properties); * } * }); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#other-amplitude-sdks-and-third-party-analytics-providers} */ addIntegration(integration: Integration): void; /** * Sets a router function that can be used during navigation to update the page's URL without triggering a reload. * Useful for Single Page Applications (SPAs) using client-side routing. * * @param routerFn - The router function that accepts a URL string * * @example * ```typescript * // With React Router * window.engagement.setRouter((url) => { * navigate(url); * }); * * // With Vue Router * window.engagement.setRouter((url) => { * router.push(url); * }); * ``` */ setRouter(routerFn: (url: string) => void): void; /** * Updates the localization locale. This will trigger a re-fetch of the config and refresh all guides and surveys. * * @param locale - The new locale code (e.g., 'en-US', 'en', 'fr-FR') * @returns Promise that resolves when the language update is complete * * @example * ```typescript * // Change to French * await window.engagement.updateLanguage('fr-FR'); * * // Change to English * await window.engagement.updateLanguage('en-US'); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#localization} */ updateLanguage(locale: string): Promise<void>; /** * Changes the current default theme to the light- or dark-mode version. * If 'auto', it will choose the user-preferred color-scheme. * * @param mode - Theme mode to set * * @example * ```typescript * // Set dark mode * window.engagement.setThemeMode('darkMode'); * * // Set light mode * window.engagement.setThemeMode('lightMode'); * * // Use system preference * window.engagement.setThemeMode('auto'); * ``` */ setThemeMode(mode: 'lightMode' | 'darkMode' | 'auto'): void; /** * Add a callback function to execute on CTA clicks. * * @param callbackKey - The callback key * @param callbackFn - The function to call * * @example * ```typescript * // Track when guides start * window.engagement.addCallback('my-callback-key', (data) => { * console.log('CTA clicked:', data); * }); * ``` */ addCallback(callbackKey: string, callbackFn: PublicCallbackFunction): void; /** * Set a session property for the current session. Session properties provide an additional way to restrict * when guides and surveys are triggered. At the time of trigger, the configured session property conditions * must be met for the guide or survey to display. * * When a session property changes, the SDK checks if there are any guides or surveys that can now be shown. * This means session properties work with the "immediately" trigger and display content as soon as the * session property conditions become true. * * **Feature availability:** Session properties are a feature-flagged capability. Contact Amplitude support * if you want to use this feature. * * @param key - The session property key to set * @param value - The value to set for the session property * * @example * ```typescript * // Set subscription tier * window.engagement.setSessionProperty('subscriptionTier', 'premium'); * * // Set user score * window.engagement.setSessionProperty('userScore', 85); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#set-session-properties} */ setSessionProperty(key: SessionPropertyKey, value: SessionPropertyValue): void; /** * Register an action on a guide or survey by its variant ID. * Used primarily for headless implementations where you're building custom UI. * * @param variantId - The variant ID of the guide or survey * @param action - The action to perform * * @example * ```typescript * // Show a guide * window.engagement.registerAction(123, { type: 'show' }); * * // Dismiss a guide * window.engagement.registerAction(123, { type: 'dismiss' }); * * // Snooze a guide * window.engagement.registerAction(123, { type: 'snooze' }); * * // Click primary button with survey responses * window.engagement.registerAction(123, { * type: 'ctaClick', * buttonType: 'primary', * surveyResponses: { * 'block-123': 'User response text' * } * }); * ``` */ registerAction( variantId: number, action: | { type: 'show' } | { type: 'dismiss' } | { type: 'snooze' } | { type: 'ctaClick'; buttonType: 'primary' | 'secondary'; surveyResponses?: { [blockId: string]: SurveyResponse }; }, ): void; /** * Sets the auto-refresh interval. Can be called after boot to change or disable the refresh interval. * * @param intervalSeconds - The interval in seconds. If not specified, 0, or negative, auto-refresh is disabled. * Must be greater than or equal to 60 seconds if enabled. * * @example * ```typescript * // Set refresh interval to 1 hour * window.engagement.setAutoRefreshInterval(3600); * * // Set refresh interval to 30 minutes * window.engagement.setAutoRefreshInterval(1800); * * // Disable auto-refresh * window.engagement.setAutoRefreshInterval(0); * ``` */ setAutoRefreshInterval(intervalSeconds?: number): void; /** * Sets a filter to restrict Resource Center content by tags. * Applies to Resource Center search and Autopilot recommendations. * * @param filter - Tag filter object or null to clear the filter * * @example * ```typescript * // Filter to content tagged "billing" OR "payments" * window.engagement.setResourceCenterFilter({ * tags: ["billing", "payments"] * }); * * // Complex filter with AND/OR logic * window.engagement.setResourceCenterFilter({ * and: [ * { tags: ["billing", "payments"] }, * { tags: ["enterprise"] } * ] * }); * * // Clear the filter * window.engagement.setResourceCenterFilter(null); * ``` */ setResourceCenterFilter(filter: TagFilter | null): void; /** * Assistant service namespace. * Provides methods to control the Assistant chat functionality. * Available after the SDK is initialized. */ assistant?: AssistantService; /** * Fetches decide data from the server. * This is typically called automatically by the SDK, but can be called manually if needed. * * @returns Promise that resolves with the decide data * * @example * ```typescript * const decideData = await window.engagement.decide(); * ``` */ decide(): Promise<any>; /** * Re-enable the SDK after it has been disabled using the "disable" method. */ enable(): void; /** * Temporarily disable the SDK, preventing any Guides or Surveys from being shown * and hiding any currently visible Guides or Surveys. * * Can be re-enabled with the "enable" method. */ disable(): void; } /** * Initializes the Engagement SDK. * This is a standalone function that can be called directly. * * @param apiKey - Amplitude API Key * @param initOptions - Optional configuration options * * @example * ```typescript * import { init } from '@amplitude/engagement-browser'; * init('YOUR_API_KEY', { serverZone: 'US' }); * ``` * * @see {@link EngagementSDK.init} */ export declare const init: (apiKey: string, initOptions?: InitOptions | undefined) => void; /** * Returns an Amplitude plugin for the Engagement SDK. * This is the recommended approach when using Amplitude Browser SDK 2.0. * * @param options - Optional configuration options * @returns Amplitude Plugin object * * @example * ```typescript * import * as amplitude from '@amplitude/analytics-browser'; * import { plugin as engagementPlugin } from '@amplitude/engagement-browser'; * * amplitude.add(engagementPlugin()); * amplitude.init('YOUR_API_KEY'); * ``` * * @see {@link EngagementSDK.plugin} * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk#amplitude-browser-sdk-2} */ export declare const plugin: (options?: InitOptions | undefined) => Plugin; /** * Global window augmentation for the Engagement SDK. * After initialization, the SDK is available on `window.engagement`. */ declare global { interface Window { /** * Amplitude Guides and Surveys SDK instance. * Available after calling `init()` or adding the plugin with `amplitude.add(engagementPlugin())`. * * @example * ```typescript * // Initialize * window.engagement.init('YOUR_API_KEY'); * * // Boot with user * await window.engagement.boot({ user: { user_id: 'user-123' } }); * * // Show a guide * window.engagement.gs.show('my-guide-key'); * * // Open Resource Center * window.engagement.rc.open(); * ``` * * @see {@link https://amplitude.com/docs/guides-and-surveys/sdk} */ engagement: EngagementSDK; } } export {};