
Amplitude's Guides and Surveys SDK enables you to deploy [Guides and Surveys](/docs/guides-and-surveys) on your website or application.

## Install the SDK

Guides and Surveys supports different installation options to work best with your existing Amplitude implementation, if you have one.

{% callout type="note" heading="Shopify installation" %}
If you use the [Amplitude Shopify Plugin](/docs/data/amplitude-shopify-plugin), install the Guides and Surveys Web SDK separately. The Shopify plugin includes Amplitude Analytics, Session Replay, and Web Experiment, but doesn't include Guides and Surveys.
{% /callout %}

### Amplitude Browser SDK 2

If you use the [Amplitude Browser SDK v2](/docs/sdks/analytics/browser/browser-sdk-2), install the Guides and Surveys SDK with a script, or as a package with npm or Yarn.

This approach uses the Amplitude Browser SDK's plugin system, which lets you extend the core Analytics SDK with additional capabilities. Calling `amplitude.add(engagementPlugin())` registers Guides and Surveys as a plugin. Guides and Surveys initializes alongside Analytics, shares the same API key and user identity, and communicates with Analytics directly. You don't need to call `init` or `boot` separately.

{% tabs tabs="script, npm, yarn" %}
{% tab name="script" %}
Place the script tag below your Amplitude script tag.

```html
<script src="https://cdn.amplitude.com/script/API_KEY.engagement.js"></script>
<script>
  amplitude.add(window.engagement.plugin());
</script>
```

{% callout type="warning" heading="Load scripts synchronously" %}
When using script tags to load Analytics and Engagement SDKs, don't set `async = true` on your Amplitude Analytics script tag. The Analytics SDK must load before the Engagement SDK. Loading them asynchronously can cause initialization errors.
{% /callout %}

{% /tab %}
{% tab name="npm" %}

```bash
npm install @amplitude/engagement-browser
```

Import Guides and Surveys into your project:

```ts
import { plugin as engagementPlugin } from "@amplitude/engagement-browser";
amplitude.add(engagementPlugin());
```

{% /tab %}
{% tab name="yarn" %}

```bash
yarn add @amplitude/engagement-browser
```

Import Guides and Surveys into your project:

```ts
import { plugin as engagementPlugin } from "@amplitude/engagement-browser";
amplitude.add(engagementPlugin());
```

{% /tab %}
{% /tabs %}

For additional configuration, supply `InitOptions` to the `plugin` function. Go to [Initialize the SDK](#initialize-the-sdk) for the available options.

For example, use `autoRefreshIntervalSeconds` to configure auto-refresh at plugin time, since the plugin calls `boot()` automatically:

```ts
import { plugin as engagementPlugin } from "@amplitude/engagement-browser";
amplitude.add(
  engagementPlugin({
    autoRefreshIntervalSeconds: 3600,
  }),
);
```

{% callout type="note" heading="" %}
After the installation steps are complete, the SDK sends all Guides and Surveys events to your project by default.
{% /callout %}

{% callout type="warning" heading="Use the same API key for Guides & Surveys and Analytics" %}
To avoid analytics mismatches and ensure accurate data collection, use the same API key for both Guides & Surveys and your Analytics SDK. Both should reference the same Amplitude project. Using different API keys can cause:

- The SDK to fetch guides and surveys from the wrong project.
- Analytics data to appear in different projects.
- Insights and survey responses to be incomplete or mismatched.

Make sure the API key you provide to Guides & Surveys matches the API key used to initialize your Amplitude Analytics SDK.
{% /callout %}

{% callout type="note" heading="No need to call init or boot" %}
When using the Amplitude Browser SDK plugin with `amplitude.add(engagementPlugin())`, don't call `engagement.init()` or `engagement.boot()`. The plugin handles initialization automatically.

Only call `init` and `boot` manually if you need to:

- Use a proxy. Refer to [Standalone installation](/docs/sdks/guides-and-surveys/sdk#standalone-installation-other-amplitude-sdks-third-party-analytics-providers-and-proxy-setups) and [Proxy configuration](/docs/guides-and-surveys/proxy).
- Customize event handling with the `integrations` option. Refer to [Standalone installation](/docs/sdks/guides-and-surveys/sdk#standalone-installation-other-amplitude-sdks-third-party-analytics-providers-and-proxy-setups).

Use this option only with the [Amplitude Analytics Browser SDK 2](/docs/sdks/analytics/browser/browser-sdk-2).
{% /callout %}

### Amplitude Browser Unified SDK

The [Amplitude Browser Unified SDK](/docs/sdks/analytics/browser/browser-unified-sdk) includes Guides and Surveys by default. Provide the engagement options during initialization:

```ts
import { initAll } from "@amplitude/unified";

initAll("YOUR_API_KEY", {
  // Other Amplitude SDK options...
  engagement: {
    // Guides and Surveys options go here...
  },
});
```

Enable Guides and Surveys in your Amplitude project settings before guides and surveys can display. Go to [Unified SDK documentation](/docs/sdks/analytics/browser/browser-unified-sdk#guides-and-surveys-options) for details.

### Standalone installation: Other Amplitude SDKs, third-party analytics providers, and proxy setups

Use this standalone installation path if you:

- Use an Amplitude SDK other than [Browser SDK 2](/docs/sdks/analytics/browser/browser-sdk-2) or [Browser Unified SDK](/docs/sdks/analytics/browser/browser-unified-sdk).
- Use a third-party analytics provider (like Segment, Heap, or Mixpanel).
- Use [Browser SDK 2](/docs/sdks/analytics/browser/browser-sdk-2) with a proxy server.

{% callout type="warning" heading="Proxy setups require standalone installation" %}
If you use Browser SDK 2 with a proxy (custom `serverUrl` in your Analytics initialization), don't use the plugin installation path (`amplitude.add(engagementPlugin())`). The plugin doesn't support proxy configuration. Instead, use this standalone installation path with `init` and `boot`, and configure the Guides and Surveys proxy URLs separately. Review [proxy configuration](/docs/guides-and-surveys/proxy) for details.
{% /callout %}

This installation requires these steps:

1. Add the Guides and Surveys SDK with the script tag, or through `npm` or `yarn`.
2. Call `init` and `boot` directly to initialize Guides and Surveys and connect it to your analytics provider.

{% callout type="warning" heading="Required and recommended setup for this installation path" %}

- **Required**: Include `integrations` in your `boot` call to send Guides and Surveys events to your analytics provider. Without it, guide insights, survey insights, and survey responses won't appear.
- **Strongly recommended**: Set up event forwarding using `forwardEvent` to enable the _On event tracked_ trigger in Guides and Surveys. Without it, you can only trigger guides and surveys on page load or other non-event conditions.

{% /callout %}

#### Initialize the SDK

Call `init` to fully initialize the bundle and register `engagement` on the global window object.

```js
engagement.init(apiKey: string, options: { serverZone: "US" | "EU", serverUrl: string, cdnUrl: string, mediaUrl: string, logger: Logger, logLevel: LogLevel, locale: string, nonce: string, autoRefreshIntervalSeconds: number, skip: boolean }): void
```

| Parameter                                | Type                                                                                                                         | Description                                                                                                                                                                                                                                                                                                                                |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `apiKey`                                 | `string`                                                                                                                     | Required. API key of the Amplitude project you want to use.                                                                                                                                                                                                                                                                                |
| `initOptions.serverZone`                 | `EU` or `US`                                                                                                                 | Optional. Sets the Amplitude server zone. Set this to `EU` for Amplitude projects created in the EU data center. Default: `US`.                                                                                                                                                                                                            |
| `initOptions.serverUrl`                  | `string`                                                                                                                     | Optional. Sets a custom server URL for API requests. Use this option for [proxy setups](/docs/guides-and-surveys/proxy). Default: `https://gs.amplitude.com` (US) or `https://gs.eu.amplitude.com` (EU).                                                                                                                                   |
| `initOptions.cdnUrl`                     | `string`                                                                                                                     | Optional. Sets a custom CDN URL for static assets. Use this option for [proxy setups](/docs/guides-and-surveys/proxy). Default: `https://cdn.amplitude.com` (US) or `https://cdn.eu.amplitude.com` (EU).                                                                                                                                   |
| `initOptions.mediaUrl`                   | `string`                                                                                                                     | Optional. Sets a custom URL for proxying nudge images. Use this option for [proxy setups](/docs/guides-and-surveys/proxy) when firewalls block images. Default: `https://engagement-static.amplitude.com` (US) or `https://engagement-static.eu.amplitude.com` (EU).                                                                       |
| `initOptions.logger`                     | [Logger interface](https://github.com/amplitude/Amplitude-TypeScript/blob/main/packages/analytics-types/src/logger.ts#L1-L8) | Optional. Sets a custom logging provider class. Default: [Amplitude Logger](https://github.com/amplitude/Amplitude-TypeScript/blob/main/packages/analytics-core/src/logger.ts)                                                                                                                                                             |
| `initOptions.logLevel`                   | `LogLevel.None` or `LogLevel.Error` or `LogLevel.Warn` or `LogLevel.Verbose` or `LogLevel.Debug`.                            | Optional. Sets the log level. Default: `LogLevel.Warn`.                                                                                                                                                                                                                                                                                    |
| `initOptions.locale`                     | `string`                                                                                                                     | Optional. Sets the locale for [localization](/docs/sdks/guides-and-surveys/sdk#localization). Default: `undefined`. If you don't set a language, the SDK uses the default language.                                                                                                                                                        |
| `initOptions.nonce`                      | `string`                                                                                                                     | Optional. Sets a nonce value for Content Security Policy (CSP) compliance. The nonce lets Guides and Surveys execute required inline styles when you enable CSP. Default: `undefined`.                                                                                                                                                     |
| `initOptions.autoRefreshIntervalSeconds` | `number`                                                                                                                     | Optional. Auto-refresh interval in seconds. The SDK automatically refreshes (re-fetches targeting data and reloads configuration) at this interval. Must be 60 seconds or greater. If not specified, 0, or negative, the SDK disables auto-refresh. In plugin mode, set this at init time since the plugin manages `boot()` automatically. |
| `initOptions.skip`                       | `boolean`                                                                                                                    | Optional. Skips initialization and doesn't set up the proxy. Call `init` again later without `skip` to initialize, then call `boot()` to start. Default: `false`.                                                                                                                                                                          |

##### Example: Basic initialization

```js
engagement.init("YOUR_API_KEY", {
  serverZone: "US",
  logLevel: LogLevel.Warn,
});
```

##### Example: Initialization with proxy

For [proxy setups](/docs/guides-and-surveys/proxy), specify `serverUrl`, `cdnUrl`, and `mediaUrl`:

```js
engagement.init("YOUR_API_KEY", {
  serverUrl: "https://your-proxy-domain.cloudfront.net",
  cdnUrl: "https://your-proxy-domain.cloudfront.net",
  mediaUrl: "https://your-proxy-domain.cloudfront.net",
});
```

{% callout type="note" heading="" %}
When using a proxy, call `window.engagement.boot` to fully install Guides and Surveys, even if you are using the Browser SDK v2. Make sure to set up event handling through the `integrations` option.
{% /callout %}

##### Example: Initialization with CSP nonce

For Content Security Policy (CSP) compliance, include a nonce value:

```js
engagement.init("YOUR_API_KEY", {
  nonce: "YOUR_NONCE",
});
```

##### Example: Initialization with auto-refresh

Enable auto-refresh to periodically re-fetch targeting data and reload configuration:

```js
engagement.init("YOUR_API_KEY", {
  autoRefreshIntervalSeconds: 3600,
});
```

##### Example: Deferred initialization with skip

Use `skip` to register `engagement` on the window object without initializing the SDK or setting up the proxy. Call `init` again later without `skip` to complete initialization, then call `boot()` to start.

```js
// Register the engagement object without initializing
engagement.init("YOUR_API_KEY", { skip: true });

// Later, when ready to initialize
engagement.init("YOUR_API_KEY", { serverZone: "US" });
engagement.boot({ user_id: "USER_ID" });
```

After calling this function, you can access `window.engagement` and call the SDK functions. Guides and Surveys isn't fully functional until you call `boot`.

#### Boot user

Call `boot` after `init` to make Guides and Surveys available to users. In standalone installations, Guides and Surveys doesn't work until you call `boot`, even if the SDK script loads on the page.

For detailed documentation on the `boot` method, including parameter options, type definitions, and usage examples, refer to [Boot](#boot).

The following example calls `boot` with a user ID, device ID, and user properties. It also specifies `integrations` to forward Guides and Surveys events to an analytics provider.

```js
await window.engagement.boot({
  user: {
    user_id: "user123",
    device_id: "device456",
    user_properties: {
      plan: "premium",
    },
  },
  integrations: [
    {
      track: (event) => {
        amplitude.track(event.event_type, event.event_properties);
      },
    },
  ],
});
```

#### Forwarding events

To use the **On event tracked** [trigger](/docs/guides-and-surveys/setup-and-target#triggers), forward events from your analytics provider to Guides and Surveys. The Guides and Surveys SDK doesn't send these events to Amplitude. The SDK uses them only for local trigger evaluation.

{% callout type="tip" heading="Strongly recommended for this installation path" %}
Amplitude strongly recommends setting up event forwarding when not using the Amplitude Browser SDK plugin. Without it, you can't use the _On event tracked_ trigger, which limits your ability to show guides and surveys based on user behavior in your app.
{% /callout %}

```js
analytics.on("track", (event, properties, options) => {
  // Example for Segment Analytics
  window.engagement.forwardEvent({
    event_type: event,
    event_properties: properties,
  });
});
```

#### Example of booting and forwarding events if using Segment

{% accordion title="Initialize with Segment analytics" %}
Initializing the SDK and launching a guide or survey with third-party analytics requires additional steps.

First, map the `user_id` and `device_id` fields. Optionally, configure event forwarding to enable event-based triggers.

{% tabs tabs="script, npm, yarn" %}
{% tab name="script" %}
Make sure you've added the Engagement script tag to your site before continuing.

```js
window.engagement.init("API_KEY", { serverZone: "US" });

analytics.ready(() => {
  await window.engagement.boot({
    user: {
      // User Provider: Guides and Surveys requires either user_id or device_id for user identification
      user_id: analytics.user().id(),
      device_id: analytics.user().anonymousId(),
      user_properties: analytics.user().traits(),
    },
    integrations: [
      {
        // Tracking Provider: Pass Guides and Surveys events to the 3rd party analytics provider
        track: (event) => {
          analytics.track(event.event_type, event.event_properties)
        }
      },
    ],
  });

  // (Strongly recommended) Forward events from Segment to enable event-based triggers for Guides and Surveys. These events aren't sent to Amplitude servers
  analytics.on('track', (event, properties, options) => {
    window.engagement.forwardEvent({ event_type: event, event_properties: properties});
  });

  analytics.on('page', (event, properties, options) => {
    window.engagement.forwardEvent({ event_type: event, event_properties: properties});
  });
});
```

{% /tab %}
{% tab name="npm" %}
Import the Guides and Surveys package

```bash
npm install @amplitude/engagement-browser
```

Connect Guides and Surveys with Segment:

```ts
import { init as engagementInit } from "@amplitude/engagement-browser";

engagementInit("API_KEY", { serverZone: "US" });

analytics.ready(() => {
  await window.engagement.boot({
    user: {
      // User Provider: Guides and Surveys requires either user_id or device_id for user identification
      user_id: analytics.user().id(),
      device_id: analytics.user().anonymousId(),
      user_properties: {},
    },
    integrations: [
      {
        // Tracking Provider: Pass Guides and Surveys events to the 3rd party analytics provider
        track: (event) => {
          analytics.track(event.event_type, event.event_properties);
        },
      },
    ],
  });

  // (Strongly recommended) Forward events from Segment to enable event-based triggers for Guides and Surveys. These events aren't sent to Amplitude servers
  analytics.on("track", (event, properties, options) => {
    window.engagement.forwardEvent({
      event_type: event,
      event_properties: properties,
    });
  });

  analytics.on("page", (event, properties, options) => {
    window.engagement.forwardEvent({
      event_type: event,
      event_properties: properties,
    });
  });
});
```

{% /tab %}
{% tab name="yarn" %}
Import the Guides and Surveys package

```bash
yarn add @amplitude/engagement-browser
```

Connect Guides and Surveys with Segment:

```ts
import { init as engagementInit } from "@amplitude/engagement-browser";

engagementInit("API_KEY", { serverZone: "US" });

analytics.ready(() => {
  await window.engagement.boot({
    user: {
      // User Provider: Guides and Surveys requires either user_id or device_id for user identification
      user_id: analytics.user().id(),
      device_id: analytics.user().anonymousId(),
      user_properties: {},
    },
    integrations: [
      {
        // Tracking Provider: Pass Guides and Surveys events to the 3rd party analytics provider
        track: (event) => {
          analytics.track(event.event_type, event.event_properties);
        },
      },
    ],
  });

  // (Strongly recommended) Forward events from Segment to enable event-based triggers for Guides and Surveys. These events aren't sent to Amplitude servers
  analytics.on("track", (event, properties, options) => {
    window.engagement.forwardEvent({
      event_type: event,
      event_properties: properties,
    });
  });

  analytics.on("page", (event, properties, options) => {
    window.engagement.forwardEvent({
      event_type: event,
      event_properties: properties,
    });
  });
});
```

{% /tab %}
{% /tabs %}
{% /accordion %}

### Google Tag Manager

If you haven't already, update to the latest version of the Amplitude template. Find the update icon on the Templates page in GTM.

Next, on the Tags page, enable Guides and Surveys.

{% callout type="info" heading="" %}
The Amplitude template doesn't enable Guides and Surveys by default. This default prevents organizations with automatic template updates from enabling Guides and Surveys accidentally.
{% /callout %}

{% callout type="warning" heading="Google Tag Manager isn't the recommended install method" %}
While Google Tag Manager is a convenient way to test the Guides and Surveys SDK, Amplitude recommends deploying through the Browser SDK v2, the Browser Unified SDK, or the standalone installation code path. GTM can cause timing and sequencing issues that affect guide and survey delivery. Installing the SDK directly through code gives you greater control over targeting, SDK usage, localization, and access to new features as the product evolves.
{% /callout %}

## Verify installation and initialization

To verify that the Guides and Surveys SDK is running on your site or dev environment, open your browser's Developer Tools, and enter the following in the console:

```js
window.engagement;
```

If the response is `undefined`, Guides and Surveys isn't installed properly.

### Content Security Policy (CSP)

If your organization has a strict Content Security Policy (CSP), Guides and Surveys requires some additions to ensure smooth operation. Add the following CSP directives to your policy:

```text
script-src: https://*.amplitude.com;
connect-src: https://*.amplitude.com;
img-src: https://*.amplitude.com;
media-src: https://*.amplitude.com;
style-src: https://*.amplitude.com;
```

For environments with stricter CSP requirements that block inline styles, use the `nonce` parameter during initialization. The parameter lets Guides and Surveys execute necessary inline styles by including your CSP nonce value:

```js
engagement.init("YOUR_API_KEY", {
  nonce: "YOUR_NONCE",
});
```

### iframe support and limitations

Guides and Surveys has limited support for applications that use iframes. Consider these limitations when implementing Guides and Surveys in iframe-based applications.

**Targeting elements inside iframes:**

- Pins and tooltips can't target elements inside an iframe from the parent application.
- Each iframe requires its own SDK instance to display guides or surveys within that iframe.
- CSS selectors can't cross iframe boundaries, which prevents the SDK from locating elements inside iframes.

**SDK instances and multi-step experiences:**

- Each iframe requires a separate SDK instance, initialized with the same API key as the parent application.
- Multi-step tours that span across the parent application and iframes aren't supported.
- Each SDK instance operates independently and can't coordinate steps across different contexts.

**Event tracking and user identification:**

- Events tracked in an iframe are independent from events in the parent application.
- Ensure consistent user identification (user ID and device ID) across all SDK instances.
- Each SDK instance maintains its own state and doesn't share data with other instances.

**Recommended approach:**

- Install the SDK in both the parent application and each iframe that needs to display guides or surveys.
- Use the same API key for all SDK instances to ensure consistent user identification.
- Design guides and surveys to work within a single context (either parent or a specific iframe).

## Troubleshoot your installation

If your Guides and Surveys instrumentation doesn't work, verify the following topics:

### Verify Guides and Surveys installation

{% callout type="tip" %}
Use the [Amplitude Chrome extension](/docs/data/chrome-extension-debug) to debug Guides & Surveys. The extension includes tools to verify SDK setup, troubleshoot why guides or surveys aren't showing, and test event-based triggers.
{% /callout %}

1. Open your browser's developer console, and enter `window.engagement`. If the return is `undefined`, Guides and Surveys installation wasn't successful.
2. If `window.engagement` returns a valid response, enter `window.engagement._.user`. A return of `undefined` indicates an issue with the Amplitude Browser SDK plugin configuration.
3. For additional debugging, enter `window.engagement._debugStatus()`. The output should look like:

```json
{
  "user": {
    "user_id": "test-base-user-1vxxkg",
    "device_id": "62c5e45a-94ab-4090-b053-3f28e848763f",
    "user_properties": {
      "foo": "bar"
    }
  },
  "apiKey": "6ae8d3d7d48eadfb0b2489db692e14c9",
  "stateInitialized": true,
  "decideSuccessful": true,
  "num_guides_surveys": 2,
  "analyticsIntegrations": 1
}
```

Verify that:

- The `user` object is present.
- `apiKey` is set.
- `stateInitialized` is `true`.
- `decideSuccessful` is `true`.
- `num_guides_surveys` is a non-zero integer if a guide or survey should display on the page.

### Verify Amplitude Browser SDK plugin configuration

If you use Amplitude Browser SDK 2.0, check the browser's console for errors. If there are none, verify that your code matches the installation instructions. In particular, ensure that `amplitude.add(window.engagement.plugin())` is present in the code.

If you see errors like `amplitude is not defined` and `cannot read properties of undefined .add()`, Guides and Surveys may load before the Amplitude SDK loads. Check your code to ensure that the Amplitude Browser SDK loads before the Guides and Surveys SDK.

Guides and Surveys requires Browser SDK 2 and doesn't support the legacy Amplitude JavaScript SDK.

### Google Tag Manager configuration

If you use Google Tag Manager, ensure you update to the latest Amplitude template.

{% callout type="warning" heading="Google Tag Manager custom tags" %}
If Guides and Surveys doesn't work with a Google Tag Manager (GTM) custom HTML tag, verify that you enabled the **Support document.write** checkbox in the tag configuration. Guides and Surveys requires this setting to load properly through GTM.

To enable this setting:

1. In GTM, navigate to your Amplitude tag.
2. Expand the **Advanced Settings** section.
3. Check the **Support document.write** checkbox.
4. Save and publish your changes.

{% /callout %}

### Common root causes

The following common errors can prevent Guides and Surveys from running.

#### `boot` runs more than once

Calling `boot` more than once causes unexpected behavior, especially for guides and surveys that should appear immediately.

{% callout type="info" heading="" %}
If you implement Guides and Surveys with `amplitude.add(window.engagement.plugin())`, don't call `boot`. The `add()` method includes this call with a very specific set of parameters.
{% /callout %}

#### Wrong project used

Ensure the API key you provide:

- Is the same key you use to initialize the Browser SDK.
- Belongs to the project that contains the Guides and Surveys configuration.

Using different API keys for Guides & Surveys and Analytics causes the SDK to fetch guides and surveys from the wrong project and results in incomplete or mismatched analytics data. Always use the same API key for both SDKs to ensure they're tied to the same Amplitude project.

## Localization

Set the `locale` option during initialization to localize a guide or survey.

- If you use the Amplitude Browser SDK 2 plugin installation (using `amplitude.add()`), set the locale in `InitOptions`.
- If you use a [third-party analytics provider](#other-amplitude-sdks-and-third-party-analytics-providers), set the locale in `options` within the `engagement.init()` method.

To dynamically update the language after the SDK initializes, use the following `updateLanguage` method. Calling `updateLanguage` re-fetches the configuration with the new locale.

```js
engagement.updateLanguage(locale: string): Promise<void>
```

| Parameter | Type     | Description                                                                              |
| --------- | -------- | ---------------------------------------------------------------------------------------- |
| `locale`  | `string` | Required. The new language code (for example, `en`, `es`, `fr`) to set for localization. |

```js
// Example: Update language to French
await window.engagement.updateLanguage("fr");

// Example: Update language to English
await window.engagement.updateLanguage("en");
```

## Preview mode for desktop apps

If you use the SDK within a desktop framework, you must perform extra instrumentation to support previewing Guides & Surveys.

The Amplitude dashboard passes your app a special query parameter through a deep link (for example, `your-app://?gs-debug-id=123`). Add logic within your app to listen for this query parameter on a deep link and call the `_startNudgeDebug` SDK method with it.

Use the following framework examples.

### Electron

Use the following minimal example to implement Guides & Surveys within Electron:

1. Register an inter-process communication function during preload.
2. In the main process: listen for and parse the `gs-debug-id` query parameter.
3. In the renderer process: listen for a message from the main process and pass the debug parameter to the Engagement SDK.

{% code-group %}
```javascript main.js
const { app } = require("electron");

// Handle deep link on macOS
app.on("open-url", (event, url) => {
  const parsedUrl = new URL(url);
  const debugId = parsedUrl.searchParams.get("gs-debug-id");

  if (debugId) {
    mainWindow.webContents.send("start-engagement-debug", {
      debugId: debugId,
    });
  }
});

// Handle deep link on Windows/Linux
app.on("second-instance", (event, commandLine, workingDirectory) => {
  // Find the deep link URL in command line arguments
  const url = commandLine.find((arg) => arg.startsWith(PROTOCOL + "://"));

  if (url) {
    const parsedUrl = new URL(url);
    const debugId = parsedUrl.searchParams.get("gs-debug-id");

    if (debugId) {
      mainWindow.webContents.send("start-engagement-debug", {
        debugId: debugId,
      });
    }
  }
});
```

```javascript preload.js
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("electronAPI", {
  startEngagementDebug: (callback) => {
    ipcRenderer.on("start-engagement-debug", (_event, data) => callback(data));
  },
});
```

```javascript renderer.js
window.electronAPI.startEngagementDebug((data) => {
  window.engagement._startNudgeDebug({
    nudge: { variantId: Number(data.debugId) },
  });
});
```
{% /code-group %}

## Lifecycle SDK methods

### Boot

Call `boot` to initialize the Guides and Surveys SDK and make it available to users. If you don't use the [Amplitude Browser SDK v2](/docs/sdks/analytics/browser/browser-sdk-2) or the [Amplitude Browser Unified SDK](/docs/sdks/analytics/browser/browser-unified-sdk), Guides and Surveys doesn't work until you call `boot`, even if the SDK script loads on the page. The method triggers targeting resolution for your live guides and surveys and establishes the connection from the Guides and Surveys SDK to your analytics provider. Call `boot` once per session unless you need to change the active user.

```js
engagement.boot(options: BootOptions): Promise<void>
```

| Parameter                            | Type                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------------------------ | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.user`                       | `EndUser`, `(() => EndUser)`, or `string` | Required. User information in one of these formats: an `EndUser` object, a function that returns a user object (useful for dynamic user data), or a simple user ID string. You must provide at least `user_id` or `device_id` in the user object. If you provide neither field, the method logs an error and returns early.                                                                                |
| `options.integrations`               | `Array<Integration>`                      | Required. An array of integrations for tracking events. Enables sending Guides and Surveys events to your analytics provider. Without integrations, guide insights, survey insights, and survey responses won't appear. Pass `[{ track: () => {} }]` as a noop if you don't need event forwarding.                                                                                                         |
| `options.autoRefreshIntervalSeconds` | `number`                                  | Deprecated. Use `autoRefreshIntervalSeconds` in `InitOptions` instead. Auto-refresh interval in seconds. When enabled, the SDK automatically refreshes (re-fetches targeting data and reloads configuration) at this interval. Must be 60 seconds or greater. If not specified, 0, or negative, the SDK disables auto-refresh. If you set both init and boot values, the boot-time value takes precedence. |

#### EndUser type

The `EndUser` type includes these properties:

| Property          | Type             | Description            |
| ----------------- | ---------------- | ---------------------- |
| `user_id`         | `string`         | User identifier        |
| `device_id`       | `string`         | Device identifier      |
| `user_properties` | `UserProperties` | Custom user properties |
| `country`         | `string`         | Country location data  |
| `region`          | `string`         | Region location data   |
| `platform`        | `string`         | Platform identifier    |

**Required fields:** You must provide at least `user_id` or `device_id`. If you provide neither field, the method logs an error and returns early.

#### Integration type

The `Integration` type includes one property:

| Property | Type                     | Description                                                   |
| -------- | ------------------------ | ------------------------------------------------------------- |
| `track`  | `(event: Event) => void` | Optional. Function to track events to your analytics provider |

#### Boot examples

**Example 1: Basic usage with user object**

```js
await window.engagement.boot({
  user: {
    user_id: "user123",
    user_properties: {
      name: "John Doe",
      plan: "premium",
      signupDate: "2023-01-15",
    },
  },
  integrations: [
    {
      track: (event) => {
        amplitude.track(event.event_type, event.event_properties);
      },
    },
  ],
});
```

**Example 2: With analytics integration**

```js
await window.engagement.boot({
  user: {
    user_id: "user123",
    device_id: "device456",
    user_properties: {
      plan: "premium",
    },
  },
  integrations: [
    {
      track: (event) => {
        amplitude.track(event.event_type, event.event_properties);
      },
    },
  ],
});
```

**Example 3: With function provider for dynamic user data**

```js
await window.engagement.boot({
  user: () => {
    return {
      user_id: getCurrentUserId(),
      device_id: getDeviceId(),
      user_properties: getUserProperties(),
    };
  },
  integrations: [
    {
      track: (event) => {
        amplitude.track(event.event_type, event.event_properties);
      },
    },
  ],
});
```

**Example 4: Simple user ID**

```js
await window.engagement.boot({
  user: "user123",
  integrations: [],
});
```

#### Boot usage requirements

- **Async method:** `boot` is an async method. Always use `await` or handle it as a Promise.
- **Required:** You must call `boot` before any guides or surveys show.
- **Queue processing:** Boot calls process first in the SDK's method queue.
- **Single call per session:** Typically call `boot` once per user session.

### Shutdown

Shut down the Guides and Surveys SDK. This method closes all active guides and surveys and stops guides and surveys from triggering. Use this method when you need to clean up the SDK completely, such as when a user logs out.

```js
engagement.shutdown(): void
```

After calling `shutdown()`, the SDK no longer functions. To use Guides and Surveys again, call `boot()` again.

### Refresh targeting

Re-fetch targeting evaluation from the backend by making a new request to the decide endpoint. Use this method to refresh which guides and surveys are eligible to show based on the latest targeting rules and user state. The SDK automatically refreshes targeting when the user or user properties change. Manually refreshing targeting is useful when you update user properties server-side or need the latest cohort membership states.

```js
engagement.decide(): Promise<void>
```

### Set auto-refresh interval

Configure automatic periodic refresh of targeting data. When enabled, the SDK automatically re-fetches decide data, refreshes the end user store, and reloads configuration at the specified interval. Auto-refresh is useful for long-running sessions where user state or targeting rules may change. A common use case is desktop applications, where pages reload less frequently than in browser environments.

```js
engagement.setAutoRefreshInterval(intervalSeconds?: number): void
```

| Parameter         | Type     | Description                                                                                                                                                                                      |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `intervalSeconds` | `number` | Optional. The interval in seconds for auto-refresh. Must be 60 seconds or greater when enabled. If you don't specify a value, or specify `0` or a negative value, the SDK disables auto-refresh. |

```js
// Set auto-refresh to every hour
window.engagement.setAutoRefreshInterval(3600);

// Set auto-refresh to every 30 minutes
window.engagement.setAutoRefreshInterval(1800);

// Disable auto-refresh
window.engagement.setAutoRefreshInterval(0);
```

You can also enable auto-refresh during boot by setting the `autoRefreshIntervalSeconds` option:

```js
await window.engagement.boot({
  user: {
    user_id: "user123",
    device_id: "device456",
  },
  autoRefreshIntervalSeconds: 3600,
});
```

{% callout type="note" heading="Minimum interval" %}
The auto-refresh interval must be 60 seconds or greater. If you specify a value less than 60 seconds, the SDK disables auto-refresh and logs a warning.
{% /callout %}

## Styling SDK methods

### Manage themes

Configure the visual theme mode if your app supports light and dark modes.

```js
engagement.setThemeMode(mode: ThemeMode): void
```

| Parameter | Type                            | Description                          |
| --------- | ------------------------------- | ------------------------------------ |
| `mode`    | `lightMode`, `darkMode`, `auto` | Required. Select the theme to apply. |

```js
// Automatically detect user's system preferences
window.engagement.setThemeMode("auto");

// Set dark mode explicitly
window.engagement.setThemeMode("darkMode");

// Set light mode explicitly
window.engagement.setThemeMode("lightMode");
```

## Instrumentation SDK methods

### Forward event

Forward third-party Analytics events to the Guides and Surveys SDK to trigger guides and surveys that use the _On event tracked_ [trigger](/docs/guides-and-surveys/setup-and-target#triggers).

```js
engagement.forwardEvent(event: Event): void
```

| Parameter | Type  | Description                                                                                                                                        |
| --------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`   | Event | Required. An [event](/docs/sdks/analytics/browser/browser-sdk-2#track-an-event) object. It triggers a guide or survey if its `event_type` matches. |

### Register a callback

Register a callback with the Guides and Surveys SDK. Set the Run callback action on a guide or survey button to execute the callback.

```js
engagement.addCallback(name: string, callback: () => void): void
```

| Parameter  | Type         | Description                                                                                   |
| ---------- | ------------ | --------------------------------------------------------------------------------------------- |
| `name`     | `string`     | Required. Refer to this callback by name when setting a callback action on a guide or survey. |
| `callback` | `() => void` | Required. The callback to execute.                                                            |

```js
window.engagement.addCallback("toggle_dark_mode", () => {
  setTheme("darkMode");
  window.engagement.setThemeMode("darkMode");
});
```

### Router configuration

Configure how Guides and Surveys handles URLs in a single page application (SPA). Doing so enables reload-less URL updates.

```js
engagement.setRouter(routerFn: (url: string) => void): void
```

| Parameter  | Type                    | Description                                           |
| ---------- | ----------------------- | ----------------------------------------------------- |
| `routerFn` | `(url: string) => void` | Required. A function that handles changes to the URL. |

```js
// React Router v6 implementation
import { useNavigate } from "react-router-dom";

const MyComponent = () => {
  const navigate = useNavigate();

  React.useEffect(() => {
    window.engagement.setRouter((newUrl) => navigate(newUrl));
  }, []);
};
```

```typescript
// Angular implementation
import { Component } from "@angular/core";
import { Router } from "@angular/router";

@Component({
  /* ... */
})
export class AppComponent {
  constructor(private router: Router) {
    window.engagement.setRouter((url: string) => {
      this.router.navigateByUrl(url);
    });
  }
}
```

For Angular apps, use the `Router` service with `navigateByUrl` in your root `AppComponent` (or an initializer). This method accepts a full URL string, which matches the `(url: string) => void` signature that `setRouter` expects.

{% callout type="note" heading="Update URL behavior" %}
After you configure the router with `setRouter()`, update the URL behavior setting in the Guides and Surveys interface. For any link actions in your guides or surveys, change the URL behavior to **Use router**. The **Same tab** and **New tab** URL behaviors don't use the configured router - only **Use router** triggers your custom router function.
{% /callout %}

### Set user properties

Set user properties for the current session. Use these properties as variables inside guides and surveys content with the `@{{ property.propertyName }}` syntax.

If you use `amplitude.identify()` to share user properties, you don't need to use `_setUserProperties()`.

{% callout type="tip" heading="" %}
Ensure that user properties load during the current client-side session and before the guide or survey displays. Properties shared from prior sessions aren't available.
{% /callout %}

```js
engagement._setUserProperties(userProperties: Record<string, any>): void
```

| Parameter        | Type                  | Description                                                                                                                     |
| ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `userProperties` | `Record<string, any>` | Required. An object that contains user properties as key-value pairs. Reference these properties in guides and surveys content. |

#### Example

```js
// Supply user properties manually via engagement SDK
const userProperties = { firstName: "john" };
engagement._setUserProperties(userProperties);

// For testing, view the current user properties
engagement._.user.user_properties;
```

### Set session properties

Set session properties for the current session. Session properties provide an additional way to restrict when guides and surveys trigger. At trigger time, the guide or survey displays only when the configured session property conditions match.

When a session property changes, the SDK checks for guides or surveys that can display. Session properties work with the "immediately" trigger and display content as soon as the session property conditions become true.

```js
engagement.setSessionProperty(key: string, value: any): void
```

| Parameter | Type     | Description                                          |
| --------- | -------- | ---------------------------------------------------- |
| `key`     | `string` | Required. The session property key to set.           |
| `value`   | `any`    | Required. The value to set for the session property. |

{% callout type="note" heading="Feature availability" %}
Session properties are a feature-flagged capability. Contact Amplitude support if you want to use this feature in your implementation.
{% /callout %}

#### Example

```js
// Various session properties to control guide/survey targeting
window.engagement.setSessionProperty("subscriptionTier", "premium");
window.engagement.setSessionProperty("isFeatureXEnabled", true);
window.engagement.setSessionProperty("userScore", 85);
```

## Guide and survey management SDK methods

### Show

Display a specific guide or survey. The SDK ignores any targeting rules and limits except for page targeting.

```js
engagement.gs.show(key: string, stepIndex?: number): void
```

| Parameter   | Type     | Description                                                                             |
| ----------- | -------- | --------------------------------------------------------------------------------------- |
| `key`       | `string` | Required. The guide or survey's key.                                                    |
| `stepIndex` | `number` | The zero-based index of the step to show. Defaults to the initial step if not provided. |

### Close all

Close all active guides and surveys.

```js
engagement.gs.closeAll(): void
```

### Reset

Reset a guide or survey to a specific step.

```js
engagement.gs.reset(key: string, stepIndex?: number)
```

| Parameter   | Type     | Description                                                                           |
| ----------- | -------- | ------------------------------------------------------------------------------------- |
| `key`       | `string` | Required. The guide or survey's key.                                                  |
| `stepIndex` | `number` | Required. The zero-based index of the step to reset to. Defaults to the initial step. |

### List

Retrieve a list of all live guides and surveys along with their status.

```js
engagement.gs.list(): Array<GuideOrSurvey>
```

```js
interface GuideOrSuvey {
  id: number;
  status: "visible" | "active";
  step: number;
  title: string
}
```
