> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK observability reference

export const pubhost_2 = "pub.observability.app.eu.launchdarkly.com"

export const otelhost_2 = "otel.observability.app.eu.launchdarkly.com"

export const pubhost_1 = "pub.observability.app.launchdarkly.com"

export const otelhost_1 = "otel.observability.app.launchdarkly.com"

export const pubhost_0 = "pub.observability.app.launchdarkly.com"

export const otelhost_0 = "otel.observability.app.launchdarkly.com"

<View title="Developer">
  This topic documents how to get started with the LaunchDarkly observability plugins for the client-side JavaScript SDK.

  The JavaScript SDK supports the following observability plugins:

  * An **Observability plugin** for error monitoring, logging, and tracing.
  * A **Session replay plugin** that provides a way to record and replay end-user sessions from your application.

  <Note>
    **SDK quick links**

    LaunchDarkly SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:

    <table>
      <thead>
        <tr>
          <th>Resource</th>
          <th>Location</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>SDK API documentation</td>
          <td>[Observability plugin API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_observe.Observe.html) <br /> [Session replay API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_record.Record.html)</td>
        </tr>

        <tr>
          <td>GitHub repository</td>
          <td>[@launchdarkly/observability](https://github.com/launchdarkly/observability-sdk/tree/main/sdk/%40launchdarkly/observability)</td>
        </tr>

        <tr>
          <td>Published module</td>
          <td>[npm](https://www.npmjs.com/package/@launchdarkly/observability)</td>
        </tr>
      </tbody>
    </table>
  </Note>

  <Warning>
    **For use in client applications only**

    These observability and session replay plugins are for the LaunchDarkly client-side JavaScript-based SDKs.

    To learn more about the different LaunchDarkly SDK types, read [Choosing an SDK type](/docs/sdk/concepts/client-side-server-side).
  </Warning>

  <Note>
    **The observability plugin replaces the JavaScript telemetry integration**

    We strongly recommend that any customers who are using the LaunchDarkly `browser-telemetry` integration now use this observability plugin instead.

    As we develop additional telemetry-related functionality, we will only be adding it to this observability plugin.
  </Note>

  ## Prerequisites and dependencies

  This reference guide assumes that you are somewhat familiar with the LaunchDarkly [JavaScript SDK](/docs/sdk/client-side/javascript).

  The observability plugin is compatible with the [JavaScript SDK](/docs/sdk/client-side/javascript), version 3.7.0 and later.

  <Tip>
    **Do you need information about Angular, Remix, Svelte, or other frameworks?**

    LaunchDarkly does not offer SDKs for all languages or frameworks. If you're using another framework, such as Angular, Remix, or Svelte, you may be able to use the JavaScript SDK instead. Install the observability plugins and initialize them when you initialize the client for the JavaScript SDK.

    To request support for a specific language or framework, [start a Support ticket](https://support.launchdarkly.com/hc/en-us/requests/new).
  </Tip>

  ## Get started

  Follow these steps to get started:

  * [Install the plugins](#install-the-plugins)
  * [Initialize the JavaScript SDK client](#initialize-the-client)
  * [Configure the plugin options](#configure-the-plugin-options)
  * [Explore supported features](#explore-supported-features)
  * [Review observability data in LaunchDarkly](#review-observability-data-in-launchdarkly)

  ## Install the plugins

  LaunchDarkly uses plugins to the JavaScript SDK to provide observability. Most customers use both the observability and session replay plugins. However, there is no dependency between them, and you can use only one or the other if you like.

  The first step is to make both the SDK and the observability plugins available as dependencies.

  Here's how:

  <CodeGroup>
    ```bash title="npm, JS SDK v4.x" lines wrap theme={null}
    npm install @launchdarkly/js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v4.x" lines wrap theme={null}
    yarn add @launchdarkly/js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```

    ```bash title="npm, JS SDK v3.7+" lines wrap theme={null}
    npm install launchdarkly-js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v3.7+" lines wrap theme={null}
    yarn add launchdarkly-js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```
  </CodeGroup>

  Then, import the plugin into your code:

  <CodeGroup>
    ```js title="Import, JS SDK v4.x" lines wrap theme={null}
    import { initialize } from "@launchdarkly/js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```

    ```js title="Import, JS SDK v3.7+" lines wrap theme={null}
    import { initialize } from "launchdarkly-js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```
  </CodeGroup>

  ## Initialize the client

  Next, initialize the SDK and the plugins.

  To initialize, you need your LaunchDarkly environment's client-side ID and, in some versions, the context for which you want to evaluate flags. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read [Initialize the client](/docs/sdk/client-side/javascript#initialize-the-client) in the JavaScript SDK reference guide.

  <Warning>
    **JavaScript observability SDK credentials**

    The JavaScript observability SDK requires a client-side ID. Client-side IDs are specific to each project and environment. They are not secret, and you can include them in client-side code. Do not embed a server-side SDK key in a client-side application.

    You can find client-side IDs and project keys on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).
  </Warning>

  You can initialize the observability plugins either at the same time you initialize the SDK, or afterwards.

  ### Initialize SDK client and plugins together

  Here's how to initialize the SDK and plugins:

  <CodeGroup>
    ```js title="Initialize, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```

    ```js title="Initialize, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```
  </CodeGroup>

  ### Initialize the plugins after the SDK client

  You can initialize the observability and session replay plugins manually, after the SDK client is initialized.

  This approach supports feature-flagged rollouts or dynamic initialization after end user consent. Both plugins use a `manualStart` option combined with `.start()` calls.

  First, configure the plugins with `manualStart: true`:

  <CodeGroup>
    ```js title="Manual start configuration, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```

    ```js title="Manual start configuration, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```
  </CodeGroup>

  Then, start the plugins when appropriate, such as after receiving end user consent or when a feature flag enables observability.

  Here's an example starting the observability plugin:

  <CodeGroup>
    ```js title="Start observability plugin" lines wrap theme={null}
    // Start observability after user consent or feature flag check
    if (userConsentReceived || featureFlagEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability with feature flag" lines wrap theme={null}
    // Example: Start observability based on a feature flag
    const observabilityEnabled = client.variation('enable-observability', false);
    if (observabilityEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability after end user action" lines wrap theme={null}
    // Example: Start observability after user accepts analytics
    const handleAcceptAnalytics = () => {
      // Store user preference
      localStorage.setItem('analyticsAccepted', 'true');

      // Start observability
      LDObserve.start();
    };
    ```
  </CodeGroup>

  Here's an example with the session replay plugin:

  <CodeGroup>
    ```js title="Start recording" lines wrap theme={null}
    LDRecord.start({
      silent: false // if true, console.warn messages created in this method are skipped
    });
    ```

    ```js title="Stop recording" lines wrap theme={null}
    LDRecord.stop();
    ```
  </CodeGroup>

  This approach lets you:

  * Feature-flag the rollout of observability to a subset of end users
  * Wait for end user consent before starting data collection
  * Dynamically enable observability based on runtime conditions
  * Maintain compliance with privacy regulations

  ## Configure the plugin options

  You can configure options for the observability plugins when you initialize the SDK. The plugin constructors take an optional object with the configuration details.

  <Note>
    **Session replays are obscured by default**

    By default, session replays use the `strict` privacy setting, which obscures some data. Use <code>none</code> to turn off session replay obfuscation. This enables more detail on session replays, but may expose more of your customer data than your privacy or data retention policies allow. To learn more, read [Session replay config](/docs/sdk/features/session-replay-config).
  </Note>

  Here is an example:

  <CodeGroup>
    ```js title="Plugin options, JS SDK v4.x" expandable lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```

    ```js title="Plugin options, JS SDK v3.7+" expandable lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```
  </CodeGroup>

  The `networkRecording` option is set separately on each plugin. On the `Observability` plugin, it controls whether request and response headers and bodies are attached to traces. On the `SessionReplay` plugin, it controls whether they appear in the Network tab of the session replay. Set it on both plugins to record headers and bodies in both places. To learn more, read [Recording network requests and WebSocket events](/docs/sdk/features/observability-config-client-side#recording-network-requests-and-websocket-events).

  For more information on plugin options, read [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side) and [Configuration for session replay](/docs/sdk/features/session-replay-config).

  ### Configure product analytics event collection

  By default, the JavaScript client-side SDK observability plugin automatically records these product analytics events as OpenTelemetry span events:

  * Page clicks, with details about the click location and URL where the click occurred.
  * Page views, with details of the current and previous URLs.
  * Custom metric events that you generate using the `track()` method. The OpenTelemetry span events for `track()` calls include the URL and metric event key, as well as any optional numeric value provided for a numeric event.

  All of the above OpenTelemetry span events also include information about the LaunchDarkly context that generated the event.

  You can use the generated span events to create custom product analytic charts, such as time series and funnels. You can also view the raw span data directly from the observability **Traces** view. To learn more, read [Traces](/docs/home/observability/traces).

  Use the `productAnalytics: false` setting in plugin options to disable collecting product analytics events, or specify individual event types to exclude.

  Here is an example:

  <CodeGroup>
    ```js title="Product analytics options, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, 
          productAnalytics: { // enable all product analytics events except for clicks
            pageViews: true,
            trackEvents: true,
            clicks: false
          }
        }),
      ]
    });
    ```
  </CodeGroup>

  <Note>
    **Product Analytics event collection is on by default**

    The JavaScript client observability plugin generates the product analytics span events by default. You only need to include `productAnalytics` in your plugin configuration if you want to disable collecting some or all events.
  </Note>

  ## Set Context-Security-Policy (CSP)

  If your application runs in an environment that enforces content security policies, you must set the `Content-Security-Policy` (CSP) in your application to tell the browser how your page can interact with third-party scripts.

  Here are the policies you need to set to use the observability plugin:

  * <code>connect-src: https\://{pubhost_0} https\://{otelhost_0}</code>: This policy allows connecting with LaunchDarkly servers to send recorded observability data.
  * `worker-src: data: blob:`: This policy allows creating an inline web worker initialized by the `npm` package for this plugin.

  Your CSP definition may look something like this:

  <CodeGroup>
    ```html title="Example CSP definition" lines wrap theme={null}
    <meta
      http-equiv="Content-Security-Policy"
      content="connect-src: https://pub.observability.app.launchdarkly.com https://otel.observability.app.launchdarkly.com; worker-src data: blob:;"
    />
    ```
  </CodeGroup>

  Alternatively, you can set the CSP in the HTML document response header `Content-Security-Policy`. Check your initial app HTML document load for the header to make sure you are setting it to the desired value.

  ## Explore supported features

  The observability plugin supports the following features. After the SDK and plugins are initialized, you can access these from within your application:

  * [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side)
  * [Configuration for session replay](/docs/sdk/features/session-replay-config#javascript)
  * [Errors](/docs/sdk/features/observability-errors#javascript)
  * [Logs](/docs/sdk/features/observability-logs#javascript)
  * [Metrics](/docs/sdk/features/observability-metrics#javascript)
  * [Tracing](/docs/sdk/features/observability-traces#javascript)

  ## Review observability data in LaunchDarkly

  After you initialize the SDK and observability plugins, your application automatically starts sending observability data back to LaunchDarkly in the form of custom events. You can review this information in the LaunchDarkly user interface. To learn how, read [Observability](/docs/home/observability).

  Specifically, the observability data includes events that LaunchDarkly uses to automatically create the following metrics:

  * Average, P95, and P99 Cumulative Layout Shift (CLS) per context (LaunchDarkly)
  * Average, P95, and P99 Document Load Latency per context (LaunchDarkly)
  * Percentage of users with errors (LaunchDarkly)
  * Average, P95, and P99 First Contentful Paint (FCP) per context (LaunchDarkly)
  * Average, P95, and P99 First Input Delay (FID) per context (LaunchDarkly)
  * Average, P95, and P99 Interaction to Next Paint (INP) per context (LaunchDarkly)
  * Average, P95, and P99 Largest Contentful Paint (LCP) (LaunchDarkly)
  * Average, P95, and P99 Time to First Byte (TTFB) per context (LaunchDarkly)

  To learn more, read [Observability autogenerated metrics](/docs/home/metrics/autogen/observability).
</View>

<View title="Federal docs">
  This topic documents how to get started with the LaunchDarkly observability plugins for the client-side JavaScript SDK.

  The JavaScript SDK supports the following observability plugins:

  * An **Observability plugin** for error monitoring, logging, and tracing.
  * A **Session replay plugin** that provides a way to record and replay end-user sessions from your application.

  <Note>
    **SDK quick links**

    LaunchDarkly SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:

    <table>
      <thead>
        <tr>
          <th>Resource</th>
          <th>Location</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>SDK API documentation</td>
          <td>[Observability plugin API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_observe.Observe.html) <br /> [Session replay API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_record.Record.html)</td>
        </tr>

        <tr>
          <td>GitHub repository</td>
          <td>[@launchdarkly/observability](https://github.com/launchdarkly/observability-sdk/tree/main/sdk/%40launchdarkly/observability)</td>
        </tr>

        <tr>
          <td>Published module</td>
          <td>[npm](https://www.npmjs.com/package/@launchdarkly/observability)</td>
        </tr>
      </tbody>
    </table>
  </Note>

  <Warning>
    **For use in client applications only**

    These observability and session replay plugins are for the LaunchDarkly client-side JavaScript-based SDKs.

    To learn more about the different LaunchDarkly SDK types, read [Choosing an SDK type](/docs/sdk/concepts/client-side-server-side).
  </Warning>

  <Note>
    **The observability plugin replaces the JavaScript telemetry integration**

    We strongly recommend that any customers who are using the LaunchDarkly `browser-telemetry` integration now use this observability plugin instead.

    As we develop additional telemetry-related functionality, we will only be adding it to this observability plugin.
  </Note>

  ## Prerequisites and dependencies

  This reference guide assumes that you are somewhat familiar with the LaunchDarkly [JavaScript SDK](/docs/sdk/client-side/javascript).

  The observability plugin is compatible with the [JavaScript SDK](/docs/sdk/client-side/javascript), version 3.7.0 and later.

  <Tip>
    **Do you need information about Angular, Remix, Svelte, or other frameworks?**

    LaunchDarkly does not offer SDKs for all languages or frameworks. If you're using another framework, such as Angular, Remix, or Svelte, you may be able to use the JavaScript SDK instead. Install the observability plugins and initialize them when you initialize the client for the JavaScript SDK.

    To request support for a specific language or framework, [start a Support ticket](https://support.launchdarkly.com/hc/en-us/requests/new).
  </Tip>

  ## Get started

  Follow these steps to get started:

  * [Install the plugins](#install-the-plugins)
  * [Initialize the JavaScript SDK client](#initialize-the-client)
  * [Configure the plugin options](#configure-the-plugin-options)
  * [Explore supported features](#explore-supported-features)
  * [Review observability data in LaunchDarkly](#review-observability-data-in-launchdarkly)

  ## Install the plugins

  LaunchDarkly uses plugins to the JavaScript SDK to provide observability. Most customers use both the observability and session replay plugins. However, there is no dependency between them, and you can use only one or the other if you like.

  The first step is to make both the SDK and the observability plugins available as dependencies.

  Here's how:

  <CodeGroup>
    ```bash title="npm, JS SDK v4.x" lines wrap theme={null}
    npm install @launchdarkly/js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v4.x" lines wrap theme={null}
    yarn add @launchdarkly/js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```

    ```bash title="npm, JS SDK v3.7+" lines wrap theme={null}
    npm install launchdarkly-js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v3.7+" lines wrap theme={null}
    yarn add launchdarkly-js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```
  </CodeGroup>

  Then, import the plugin into your code:

  <CodeGroup>
    ```js title="Import, JS SDK v4.x" lines wrap theme={null}
    import { initialize } from "@launchdarkly/js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```

    ```js title="Import, JS SDK v3.7+" lines wrap theme={null}
    import { initialize } from "launchdarkly-js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```
  </CodeGroup>

  ## Initialize the client

  Next, initialize the SDK and the plugins.

  To initialize, you need your LaunchDarkly environment's client-side ID and, in some versions, the context for which you want to evaluate flags. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read [Initialize the client](/docs/sdk/client-side/javascript#initialize-the-client) in the JavaScript SDK reference guide.

  <Warning>
    **JavaScript observability SDK credentials**

    The JavaScript observability SDK requires a client-side ID. Client-side IDs are specific to each project and environment. They are not secret, and you can include them in client-side code. Do not embed a server-side SDK key in a client-side application.

    You can find client-side IDs and project keys on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).
  </Warning>

  You can initialize the observability plugins either at the same time you initialize the SDK, or afterwards.

  ### Initialize SDK client and plugins together

  Here's how to initialize the SDK and plugins:

  <CodeGroup>
    ```js title="Initialize, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```

    ```js title="Initialize, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```
  </CodeGroup>

  ### Initialize the plugins after the SDK client

  You can initialize the observability and session replay plugins manually, after the SDK client is initialized.

  This approach supports feature-flagged rollouts or dynamic initialization after end user consent. Both plugins use a `manualStart` option combined with `.start()` calls.

  First, configure the plugins with `manualStart: true`:

  <CodeGroup>
    ```js title="Manual start configuration, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```

    ```js title="Manual start configuration, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```
  </CodeGroup>

  Then, start the plugins when appropriate, such as after receiving end user consent or when a feature flag enables observability.

  Here's an example starting the observability plugin:

  <CodeGroup>
    ```js title="Start observability plugin" lines wrap theme={null}
    // Start observability after user consent or feature flag check
    if (userConsentReceived || featureFlagEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability with feature flag" lines wrap theme={null}
    // Example: Start observability based on a feature flag
    const observabilityEnabled = client.variation('enable-observability', false);
    if (observabilityEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability after end user action" lines wrap theme={null}
    // Example: Start observability after user accepts analytics
    const handleAcceptAnalytics = () => {
      // Store user preference
      localStorage.setItem('analyticsAccepted', 'true');

      // Start observability
      LDObserve.start();
    };
    ```
  </CodeGroup>

  Here's an example with the session replay plugin:

  <CodeGroup>
    ```js title="Start recording" lines wrap theme={null}
    LDRecord.start({
      silent: false // if true, console.warn messages created in this method are skipped
    });
    ```

    ```js title="Stop recording" lines wrap theme={null}
    LDRecord.stop();
    ```
  </CodeGroup>

  This approach lets you:

  * Feature-flag the rollout of observability to a subset of end users
  * Wait for end user consent before starting data collection
  * Dynamically enable observability based on runtime conditions
  * Maintain compliance with privacy regulations

  ## Configure the plugin options

  You can configure options for the observability plugins when you initialize the SDK. The plugin constructors take an optional object with the configuration details.

  <Note>
    **Session replays are obscured by default**

    By default, session replays use the `strict` privacy setting, which obscures some data. Use <code>none</code> to turn off session replay obfuscation. This enables more detail on session replays, but may expose more of your customer data than your privacy or data retention policies allow. To learn more, read [Session replay config](/docs/sdk/features/session-replay-config).
  </Note>

  Here is an example:

  <CodeGroup>
    ```js title="Plugin options, JS SDK v4.x" expandable lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```

    ```js title="Plugin options, JS SDK v3.7+" expandable lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```
  </CodeGroup>

  The `networkRecording` option is set separately on each plugin. On the `Observability` plugin, it controls whether request and response headers and bodies are attached to traces. On the `SessionReplay` plugin, it controls whether they appear in the Network tab of the session replay. Set it on both plugins to record headers and bodies in both places. To learn more, read [Recording network requests and WebSocket events](/docs/sdk/features/observability-config-client-side#recording-network-requests-and-websocket-events).

  For more information on plugin options, read [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side) and [Configuration for session replay](/docs/sdk/features/session-replay-config).

  ### Configure product analytics event collection

  By default, the JavaScript client-side SDK observability plugin automatically records these product analytics events as OpenTelemetry span events:

  * Page clicks, with details about the click location and URL where the click occurred.
  * Page views, with details of the current and previous URLs.
  * Custom metric events that you generate using the `track()` method. The OpenTelemetry span events for `track()` calls include the URL and metric event key, as well as any optional numeric value provided for a numeric event.

  All of the above OpenTelemetry span events also include information about the LaunchDarkly context that generated the event.

  You can use the generated span events to create custom product analytic charts, such as time series and funnels. You can also view the raw span data directly from the observability **Traces** view. To learn more, read [Traces](/docs/home/observability/traces).

  Use the `productAnalytics: false` setting in plugin options to disable collecting product analytics events, or specify individual event types to exclude.

  Here is an example:

  <CodeGroup>
    ```js title="Product analytics options, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, 
          productAnalytics: { // enable all product analytics events except for clicks
            pageViews: true,
            trackEvents: true,
            clicks: false
          }
        }),
      ]
    });
    ```
  </CodeGroup>

  <Note>
    **Product Analytics event collection is on by default**

    The JavaScript client observability plugin generates the product analytics span events by default. You only need to include `productAnalytics` in your plugin configuration if you want to disable collecting some or all events.
  </Note>

  ## Set Context-Security-Policy (CSP)

  If your application runs in an environment that enforces content security policies, you must set the `Content-Security-Policy` (CSP) in your application to tell the browser how your page can interact with third-party scripts.

  Here are the policies you need to set to use the observability plugin:

  * <code>connect-src: https\://{pubhost_1} https\://{otelhost_1}</code>: This policy allows connecting with LaunchDarkly servers to send recorded observability data.
  * `worker-src: data: blob:`: This policy allows creating an inline web worker initialized by the `npm` package for this plugin.

  Your CSP definition may look something like this:

  <CodeGroup>
    ```html title="Example CSP definition" lines wrap theme={null}
    <meta
      http-equiv="Content-Security-Policy"
      content="connect-src: https://pub.observability.app.launchdarkly.com https://otel.observability.app.launchdarkly.com; worker-src data: blob:;"
    />
    ```
  </CodeGroup>

  Alternatively, you can set the CSP in the HTML document response header `Content-Security-Policy`. Check your initial app HTML document load for the header to make sure you are setting it to the desired value.

  ## Explore supported features

  The observability plugin supports the following features. After the SDK and plugins are initialized, you can access these from within your application:

  * [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side)
  * [Configuration for session replay](/docs/sdk/features/session-replay-config#javascript)
  * [Errors](/docs/sdk/features/observability-errors#javascript)
  * [Logs](/docs/sdk/features/observability-logs#javascript)
  * [Metrics](/docs/sdk/features/observability-metrics#javascript)
  * [Tracing](/docs/sdk/features/observability-traces#javascript)

  ## Review observability data in LaunchDarkly

  After you initialize the SDK and observability plugins, your application automatically starts sending observability data back to LaunchDarkly in the form of custom events. You can review this information in the LaunchDarkly user interface. To learn how, read [Observability](/docs/home/observability).

  Specifically, the observability data includes events that LaunchDarkly uses to automatically create the following metrics:

  * Average, P95, and P99 Cumulative Layout Shift (CLS) per context (LaunchDarkly)
  * Average, P95, and P99 Document Load Latency per context (LaunchDarkly)
  * Percentage of users with errors (LaunchDarkly)
  * Average, P95, and P99 First Contentful Paint (FCP) per context (LaunchDarkly)
  * Average, P95, and P99 First Input Delay (FID) per context (LaunchDarkly)
  * Average, P95, and P99 Interaction to Next Paint (INP) per context (LaunchDarkly)
  * Average, P95, and P99 Largest Contentful Paint (LCP) (LaunchDarkly)
  * Average, P95, and P99 Time to First Byte (TTFB) per context (LaunchDarkly)

  To learn more, read [Observability autogenerated metrics](/docs/home/metrics/autogen/observability).
</View>

<View title="EU docs">
  This topic documents how to get started with the LaunchDarkly observability plugins for the client-side JavaScript SDK.

  The JavaScript SDK supports the following observability plugins:

  * An **Observability plugin** for error monitoring, logging, and tracing.
  * A **Session replay plugin** that provides a way to record and replay end-user sessions from your application.

  <Note>
    **SDK quick links**

    LaunchDarkly SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:

    <table>
      <thead>
        <tr>
          <th>Resource</th>
          <th>Location</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>SDK API documentation</td>
          <td>[Observability plugin API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_observe.Observe.html) <br /> [Session replay API docs](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_record.Record.html)</td>
        </tr>

        <tr>
          <td>GitHub repository</td>
          <td>[@launchdarkly/observability](https://github.com/launchdarkly/observability-sdk/tree/main/sdk/%40launchdarkly/observability)</td>
        </tr>

        <tr>
          <td>Published module</td>
          <td>[npm](https://www.npmjs.com/package/@launchdarkly/observability)</td>
        </tr>
      </tbody>
    </table>
  </Note>

  <Warning>
    **For use in client applications only**

    These observability and session replay plugins are for the LaunchDarkly client-side JavaScript-based SDKs.

    To learn more about the different LaunchDarkly SDK types, read [Choosing an SDK type](/docs/sdk/concepts/client-side-server-side).
  </Warning>

  <Note>
    **The observability plugin replaces the JavaScript telemetry integration**

    We strongly recommend that any customers who are using the LaunchDarkly `browser-telemetry` integration now use this observability plugin instead.

    As we develop additional telemetry-related functionality, we will only be adding it to this observability plugin.
  </Note>

  ## Prerequisites and dependencies

  This reference guide assumes that you are somewhat familiar with the LaunchDarkly [JavaScript SDK](/docs/sdk/client-side/javascript).

  The observability plugin is compatible with the [JavaScript SDK](/docs/sdk/client-side/javascript), version 3.7.0 and later.

  <Tip>
    **Do you need information about Angular, Remix, Svelte, or other frameworks?**

    LaunchDarkly does not offer SDKs for all languages or frameworks. If you're using another framework, such as Angular, Remix, or Svelte, you may be able to use the JavaScript SDK instead. Install the observability plugins and initialize them when you initialize the client for the JavaScript SDK.

    To request support for a specific language or framework, [start a Support ticket](https://support.launchdarkly.com/hc/en-us/requests/new).
  </Tip>

  ## Get started

  Follow these steps to get started:

  * [Install the plugins](#install-the-plugins)
  * [Initialize the JavaScript SDK client](#initialize-the-client)
  * [Configure the plugin options](#configure-the-plugin-options)
  * [Explore supported features](#explore-supported-features)
  * [Review observability data in LaunchDarkly](#review-observability-data-in-launchdarkly)

  ## Install the plugins

  LaunchDarkly uses plugins to the JavaScript SDK to provide observability. Most customers use both the observability and session replay plugins. However, there is no dependency between them, and you can use only one or the other if you like.

  The first step is to make both the SDK and the observability plugins available as dependencies.

  Here's how:

  <CodeGroup>
    ```bash title="npm, JS SDK v4.x" lines wrap theme={null}
    npm install @launchdarkly/js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v4.x" lines wrap theme={null}
    yarn add @launchdarkly/js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```

    ```bash title="npm, JS SDK v3.7+" lines wrap theme={null}
    npm install launchdarkly-js-client-sdk
    npm install @launchdarkly/observability
    npm install @launchdarkly/session-replay
    ```

    ```bash title="yarn, JS SDK v3.7+" lines wrap theme={null}
    yarn add launchdarkly-js-client-sdk
    yarn add @launchdarkly/observability
    yarn add @launchdarkly/session-replay
    ```
  </CodeGroup>

  Then, import the plugin into your code:

  <CodeGroup>
    ```js title="Import, JS SDK v4.x" lines wrap theme={null}
    import { initialize } from "@launchdarkly/js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```

    ```js title="Import, JS SDK v3.7+" lines wrap theme={null}
    import { initialize } from "launchdarkly-js-client-sdk";
    import Observability, { LDObserve } from "@launchdarkly/observability";
    import SessionReplay, { LDRecord } from "@launchdarkly/session-replay";
    ```
  </CodeGroup>

  ## Initialize the client

  Next, initialize the SDK and the plugins.

  To initialize, you need your LaunchDarkly environment's client-side ID and, in some versions, the context for which you want to evaluate flags. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read [Initialize the client](/docs/sdk/client-side/javascript#initialize-the-client) in the JavaScript SDK reference guide.

  <Warning>
    **JavaScript observability SDK credentials**

    The JavaScript observability SDK requires a client-side ID. Client-side IDs are specific to each project and environment. They are not secret, and you can include them in client-side code. Do not embed a server-side SDK key in a client-side application.

    You can find client-side IDs and project keys on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).
  </Warning>

  You can initialize the observability plugins either at the same time you initialize the SDK, or afterwards.

  ### Initialize SDK client and plugins together

  Here's how to initialize the SDK and plugins:

  <CodeGroup>
    ```js title="Initialize, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```

    ```js title="Initialize, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [ new Observability(), new SessionReplay() ]
    });
    ```
  </CodeGroup>

  ### Initialize the plugins after the SDK client

  You can initialize the observability and session replay plugins manually, after the SDK client is initialized.

  This approach supports feature-flagged rollouts or dynamic initialization after end user consent. Both plugins use a `manualStart` option combined with `.start()` calls.

  First, configure the plugins with `manualStart: true`:

  <CodeGroup>
    ```js title="Manual start configuration, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```

    ```js title="Manual start configuration, JS SDK v3.7+" lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({ manualStart: true }),
        new SessionReplay({ manualStart: true })
      ]
    });
    ```
  </CodeGroup>

  Then, start the plugins when appropriate, such as after receiving end user consent or when a feature flag enables observability.

  Here's an example starting the observability plugin:

  <CodeGroup>
    ```js title="Start observability plugin" lines wrap theme={null}
    // Start observability after user consent or feature flag check
    if (userConsentReceived || featureFlagEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability with feature flag" lines wrap theme={null}
    // Example: Start observability based on a feature flag
    const observabilityEnabled = client.variation('enable-observability', false);
    if (observabilityEnabled) {
      LDObserve.start();
    }
    ```

    ```js title="Start observability after end user action" lines wrap theme={null}
    // Example: Start observability after user accepts analytics
    const handleAcceptAnalytics = () => {
      // Store user preference
      localStorage.setItem('analyticsAccepted', 'true');

      // Start observability
      LDObserve.start();
    };
    ```
  </CodeGroup>

  Here's an example with the session replay plugin:

  <CodeGroup>
    ```js title="Start recording" lines wrap theme={null}
    LDRecord.start({
      silent: false // if true, console.warn messages created in this method are skipped
    });
    ```

    ```js title="Stop recording" lines wrap theme={null}
    LDRecord.stop();
    ```
  </CodeGroup>

  This approach lets you:

  * Feature-flag the rollout of observability to a subset of end users
  * Wait for end user consent before starting data collection
  * Dynamically enable observability based on runtime conditions
  * Maintain compliance with privacy regulations

  ## Configure the plugin options

  You can configure options for the observability plugins when you initialize the SDK. The plugin constructors take an optional object with the configuration details.

  <Note>
    **Session replays are obscured by default**

    By default, session replays use the `strict` privacy setting, which obscures some data. Use <code>none</code> to turn off session replay obfuscation. This enables more detail on session replays, but may expose more of your customer data than your privacy or data retention policies allow. To learn more, read [Session replay config](/docs/sdk/features/session-replay-config).
  </Note>

  Here is an example:

  <CodeGroup>
    ```js title="Plugin options, JS SDK v4.x" expandable lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```

    ```js title="Plugin options, JS SDK v3.7+" expandable lines wrap theme={null}
    // You'll need this context later, but you can ignore it for now.
    const context = {
      kind: 'user',
      key: 'example-context-key'
    };

    const client = initialize('example-client-side-id', context, {
      plugins: [
        new Observability({
          tracingOrigins: true, // attribute frontend requests to backend domains
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true
          }
        }),
        new SessionReplay({
          networkRecording: {
            enabled: true,
            recordHeadersAndBody: true // also show headers and bodies in the session replay Network tab
          },
          privacySetting: 'strict',
          // or 'default' to redact text matching common regex for PII
          // or 'none' to turn off obfuscation
        })
      ]
    });
    ```
  </CodeGroup>

  The `networkRecording` option is set separately on each plugin. On the `Observability` plugin, it controls whether request and response headers and bodies are attached to traces. On the `SessionReplay` plugin, it controls whether they appear in the Network tab of the session replay. Set it on both plugins to record headers and bodies in both places. To learn more, read [Recording network requests and WebSocket events](/docs/sdk/features/observability-config-client-side#recording-network-requests-and-websocket-events).

  For more information on plugin options, read [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side) and [Configuration for session replay](/docs/sdk/features/session-replay-config).

  ### Configure product analytics event collection

  By default, the JavaScript client-side SDK observability plugin automatically records these product analytics events as OpenTelemetry span events:

  * Page clicks, with details about the click location and URL where the click occurred.
  * Page views, with details of the current and previous URLs.
  * Custom metric events that you generate using the `track()` method. The OpenTelemetry span events for `track()` calls include the URL and metric event key, as well as any optional numeric value provided for a numeric event.

  All of the above OpenTelemetry span events also include information about the LaunchDarkly context that generated the event.

  You can use the generated span events to create custom product analytic charts, such as time series and funnels. You can also view the raw span data directly from the observability **Traces** view. To learn more, read [Traces](/docs/home/observability/traces).

  Use the `productAnalytics: false` setting in plugin options to disable collecting product analytics events, or specify individual event types to exclude.

  Here is an example:

  <CodeGroup>
    ```js title="Product analytics options, JS SDK v4.x" lines wrap theme={null}
    const client = initialize('example-client-side-id', {
      plugins: [
        new Observability({
          tracingOrigins: true, 
          productAnalytics: { // enable all product analytics events except for clicks
            pageViews: true,
            trackEvents: true,
            clicks: false
          }
        }),
      ]
    });
    ```
  </CodeGroup>

  <Note>
    **Product Analytics event collection is on by default**

    The JavaScript client observability plugin generates the product analytics span events by default. You only need to include `productAnalytics` in your plugin configuration if you want to disable collecting some or all events.
  </Note>

  ## Set Context-Security-Policy (CSP)

  If your application runs in an environment that enforces content security policies, you must set the `Content-Security-Policy` (CSP) in your application to tell the browser how your page can interact with third-party scripts.

  Here are the policies you need to set to use the observability plugin:

  * <code>connect-src: https\://{pubhost_2} https\://{otelhost_2}</code>: This policy allows connecting with LaunchDarkly servers to send recorded observability data.
  * `worker-src: data: blob:`: This policy allows creating an inline web worker initialized by the `npm` package for this plugin.

  Your CSP definition may look something like this:

  <CodeGroup>
    ```html title="Example CSP definition" lines wrap theme={null}
    <meta
      http-equiv="Content-Security-Policy"
      content="connect-src: https://pub.observability.app.eu.launchdarkly.com https://otel.observability.app.eu.launchdarkly.com; worker-src data: blob:;"
    />
    ```
  </CodeGroup>

  Alternatively, you can set the CSP in the HTML document response header `Content-Security-Policy`. Check your initial app HTML document load for the header to make sure you are setting it to the desired value.

  ## Explore supported features

  The observability plugin supports the following features. After the SDK and plugins are initialized, you can access these from within your application:

  * [Configuration for client-side observability](/docs/sdk/features/observability-config-client-side)
  * [Configuration for session replay](/docs/sdk/features/session-replay-config#javascript)
  * [Errors](/docs/sdk/features/observability-errors#javascript)
  * [Logs](/docs/sdk/features/observability-logs#javascript)
  * [Metrics](/docs/sdk/features/observability-metrics#javascript)
  * [Tracing](/docs/sdk/features/observability-traces#javascript)

  ## Review observability data in LaunchDarkly

  After you initialize the SDK and observability plugins, your application automatically starts sending observability data back to LaunchDarkly in the form of custom events. You can review this information in the LaunchDarkly user interface. To learn how, read [Observability](/docs/home/observability).

  Specifically, the observability data includes events that LaunchDarkly uses to automatically create the following metrics:

  * Average, P95, and P99 Cumulative Layout Shift (CLS) per context (LaunchDarkly)
  * Average, P95, and P99 Document Load Latency per context (LaunchDarkly)
  * Percentage of users with errors (LaunchDarkly)
  * Average, P95, and P99 First Contentful Paint (FCP) per context (LaunchDarkly)
  * Average, P95, and P99 First Input Delay (FID) per context (LaunchDarkly)
  * Average, P95, and P99 Interaction to Next Paint (INP) per context (LaunchDarkly)
  * Average, P95, and P99 Largest Contentful Paint (LCP) (LaunchDarkly)
  * Average, P95, and P99 Time to First Byte (TTFB) per context (LaunchDarkly)

  To learn more, read [Observability autogenerated metrics](/docs/home/metrics/autogen/observability).
</View>
