> ## 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.

# Setting up the LaunchDarkly developer toolbar

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic describes how to install the LaunchDarkly developer toolbar. You can install and configure the toolbar directly in your codebase, and use it in your browser during local development.

<Warning>
  **Do not use the toolbar in production**

  You should use the toolbar only in a local dev environment. Do not render it in hosted or production environments.
</Warning>

## Prerequisites

To begin using the developer toolbar, you need:

* [A client-side ID for your LaunchDarkly environment](/docs/home/account/environment/keys#view-or-copy-sdk-credentials)
* The [LaunchDarkly JavaScript SDK](/docs/sdk/client-side/javascript#install-the-sdk) version 3.9.0 or higher
* Depending on your installation method, you may need one of the following:
  * [React](https://react.dev/) version 18.x or higher
  * [Angular](https://angular.dev/) version 14.x or higher
  * [Vue](https://v2.vuejs.org/) version 2.7 or higher

## Installation

Depending on your package manager, install the toolbar package using one of the following methods:

<CodeGroup>
  ```bash title="npm" lines wrap theme={null}
  npm install @launchdarkly/toolbar@latest
  ```

  ```bash title="yarn" lines wrap theme={null}
  yarn add @launchdarkly/toolbar@latest
  ```

  ```bash title="pnpm" lines wrap theme={null}
  pnpm add @launchdarkly/toolbar@latest
  ```
</CodeGroup>

Then, install the developer toolbar using one of the following methods:

* React
* Vue
* Angular
* using a CDN

The Developer Toolbar depends on your LaunchDarkly JavaScript client having a reference to the same `FlagOverridePlugin` and `EventInterceptionPlugin` that you pass into the developer toolbar. Be sure that that you instantiate the toolbar at the same time or immediately after you initiate the client.

<AccordionGroup>
  <Accordion title="Install using React">
    ### Install using React

    If you develop your front end using React, the `@launchdarkly/toolbar` package provides a React hook to configure and lazily-load the developer toolbar.

    After you install the package, navigate to the area of your application where you instantiate your LaunchDarkly React client. The developer toolbar uses two plugins to power its functionality, and those plugins also need to be passed into the LaunchDarkly React client.

    To do this:

    <CodeGroup>
      ```js title="Pass plugins to the client" expandable lines wrap theme={null}
      import { render } from 'react-dom';
      import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
      import { 
        useLaunchDarklyToolbar, 
        FlagOverridePlugin, 
        EventInterceptionPlugin 
      } from '@launchdarkly/toolbar';

      // Pass the same instance of these plugins into both the LaunchDarkly
      // React client as well as the developer toolbar
      const flagOverridePlugin = new FlagOverridePlugin();
      const eventInterceptionPlugin = new EventInterceptionPlugin();

      (async () => {
        const LDProvider = await asyncWithLDProvider({
          clientSideID: 'example-client-side-id',
          context: {
            kind: 'user',
            key: 'example-user-key',
            name: 'Sandy Smith',
            email: 'sandy@example.com',
          },
          options: {
            plugins: [
              flagOverridePlugin,
              eventInterceptionPlugin,
              // other plugins...
            ],
            // other options...
          },
        });

        function App() {
          // Initialize toolbar with the same plugin instances
          useLaunchDarklyToolbar({
            flagOverridePlugin, // For flag overrides (SDK Mode only)
            eventInterceptionPlugin, // For event monitoring (works in both modes)

            // OR Dev Server Mode: Connect to LaunchDarkly dev server
            devServerUrl: 'http://localhost:8080',
            projectKey: 'my-project', // Optional: auto-detects if not provided

            // Common options
            position: 'bottom-right',
            enabled: process.env.NODE_ENV === 'development' // disable in production/hosted environments
          });

          return <YourApp />;
        }

        render(
          <LDProvider>
            <App />
          </LDProvider>,
          document.getElementById('root'),
        );
      })();
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Install using Vue">
    ### Install using Vue

    After you install the package, navigate to the area of your application where you instantiate your LaunchDarkly Vue client and install the following:

    <CodeGroup>
      ```js title="Vue Composable" expandable lines wrap theme={null}
      import { onMounted } from 'vue';
      import * as LDClient from 'launchdarkly-js-client-sdk';
      import { useLaunchDarklyToolbar } from '@launchdarkly/toolbar/vue';
      import { FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar/plugins';

      const flagOverridePlugin = new FlagOverridePlugin();
      const eventInterceptionPlugin = new EventInterceptionPlugin();

      // Initialize LaunchDarkly client
      const client = LDClient.initialize(
        'client-side-id-123abc',
        {
          kind: 'user',
          key: 'user-key-123abc',
          name: 'Sandy Smith',
          email: 'sandy@example.com',
        },
        {
          plugins: [flagOverridePlugin, eventInterceptionPlugin],
        },
      );

      // In your Vue component or setup function
      export default {
        setup() {
          onMounted(async () => {
            await client.waitForInitialization();
          });

          // Initialize toolbar with the same plugin instances
          useLaunchDarklyToolbar({
            flagOverridePlugin,
            eventInterceptionPlugin,

            // OR Dev Server Mode
            devServerUrl: 'http://localhost:8080',
            projectKey: 'my-project',

            position: 'bottom-right',
            enabled: import.meta.env.DEV, // Vite
            // enabled: process.env.NODE_ENV === 'development', // Webpack
          });

          return {
            // your component data
          };
        },
      };
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Install using Angular">
    ### Install using Angular

    After you install the package, navigate to the area of your application where you instantiate your LaunchDarkly client and install the following:

    <CodeGroup>
      ```js title="Angular Service" expandable lines wrap theme={null}
      import { Component, OnInit } from '@angular/core';
      import * as LDClient from 'launchdarkly-js-client-sdk';
      import LaunchDarklyToolbarService from '@launchdarkly/toolbar/angular';
      import { FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar/plugins';
      import { environment } from '../environments/environment';

      @Component({
        selector: 'app-root',
        template: `<router-outlet></router-outlet>`,
        providers: [LaunchDarklyToolbarService],
      })
      export class AppComponent implements OnInit {
        private flagOverridePlugin = new FlagOverridePlugin();
        private eventInterceptionPlugin = new EventInterceptionPlugin();
        private ldClient: LDClient.LDClient;

        constructor(private toolbarService: LaunchDarklyToolbarService) {
          // Initialize LaunchDarkly client
          this.ldClient = LDClient.initialize(
            'client-side-id-123abc',
            {
              kind: 'user',
              key: 'user-key-123abc',
              name: 'Sandy Smith',
              email: 'sandy@example.com',
            },
            {
              plugins: [this.flagOverridePlugin, this.eventInterceptionPlugin],
            },
          );
        }

        async ngOnInit() {
          await this.ldClient.waitForInitialization();

          // Initialize toolbar with the same plugin instances
          if (!environment.production) {
            await this.toolbarService.initialize({
              flagOverridePlugin: this.flagOverridePlugin,
              eventInterceptionPlugin: this.eventInterceptionPlugin,

              // OR Dev Server Mode
              devServerUrl: 'http://localhost:8080',
              projectKey: 'my-project',

              position: 'bottom-right',
              enabled: true,
            });
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Install using a CDN">
    ### Install using a CDN

    If you are not using React, Vue, or Angular as your front-end framework, or want to use the developer toolbar in a way where it is decoupled from your tech stack and its dependencies, you can also instantiate the toolbar using a CDN.

    To do so, add this script to your `index.html` file:

    <CodeGroup>
      ```html title="index.html script" lines wrap theme={null}
      <script src="https://unpkg.com/@launchdarkly/toolbar@latest/cdn/toolbar.min.js"></script>
      ```
    </CodeGroup>

    This attaches `LaunchDarklyToolbar` to your `window` and exposes an `init()` method using `window.LaunchDarklyToolbar.init()` that will lazily load the developer toolbar in the same way the React hook does.

    In your corresponding code, wherever you instantiate your LaunchDarkly JavaScript client, pass in the following plugins:

    <CodeGroup>
      ```js title="Pass plugins to the client" expandable lines wrap theme={null}
      import * as LDClient from 'launchdarkly-js-client-sdk';
      import { FlagOverridePlugin, EventInterceptionPlugin } from '@launchdarkly/toolbar';

      // Pass these plugins into both the JS client and 
      // the window.LaunchDarklyToolbar.init() call.
      const flagOverridePlugin = new FlagOverridePlugin();
      const eventInterceptionPlugin = new EventInterceptionPlugin();

      const context: LDClient.LDContext = {
        kind: 'user',
        key: 'example-context-key',
      };

      const client = LDClient.initialize('example-client-side-id', context, {
        plugins: [
          flagOverridePlugin,
          eventInterceptionPlugin,
          // other plugins...
        ],
        // other options...
      });

      try {
        await client.waitForInitialization(5);
        // initialization succeeded, flag values are now available
        handleInitializedClient(client);
      } catch (err) {
        // initialization failed or did not complete before timeout
      }

      // Only initialize the toolbar in local environments
      if (process.env.NODE_ENV === 'development' && window.LaunchDarklyToolbar) {
        window.LaunchDarklyToolbar.init({
          flagOverridePlugin,
          eventInterceptionPlugin,
          // other toolbar options...
        });
      }
      ```
    </CodeGroup>

    If you are using TypeScript and want type-safety for the `window.LaunchDarklyToolbar.init` call, you can add a `window.d.ts` file to the root of your web application with the following:

    <CodeGroup>
      ```ts title="Add a window.d.ts file" lines wrap theme={null}
      import type { LaunchDarklyToolbar } from '@launchdarkly/toolbar';

      declare global {
        interface Window {
          LaunchDarklyToolbar?: LaunchDarklyToolbar;
        }
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Mode options

The developer toolbar supports running in two different modes:

* **SDK mode**: Integrates with your LaunchDarkly SDK for local flag overrides and testing
* **Dev server mode**: Connects to a LaunchDarkly CLI dev server for flag browsing and real-time updates

SDK mode is the default mode for the toolbar. The toolbar switches to dev server mode only if you provide `devServerUrl`. Generally, we recommend SDK mode.

### Available features by mode

<table>
  <thead>
    <tr>
      <th>Mode</th>
      <th>Options</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>SDK mode</td>

      <td>
        Flag overrides (if you provide `flagOverridePlugin`)<br />
        Events (if you provide `eventInterceptionPlugin`)<br />
        Settings
      </td>
    </tr>

    <tr>
      <td>Dev server mode</td>

      <td>
        Flags<br />
        Settings
      </td>
    </tr>
  </tbody>
</table>

### Set up SDK mode

SDK mode integrates directly with your LaunchDarkly client, allowing you to:

* Override flag values locally without affecting other members
* Test different flag variations instantly
* Work offline or with any LaunchDarkly environment

Setup requires the following steps:

1. Create a `FlagOverridePlugin` instance
2. (Optional) Create an `EventInterceptionPlugin` instance
3. Pass the plugin into your LaunchDarkly SDK's plugins array
4. Pass the same plugin instance into the `LaunchDarklyToolbar` component
5. Wrap your app with the `LDProvider`

Here's how to set up SDK mode:

<CodeGroup>
  ```tsx title="SDK mode setup" expandable lines wrap theme={null}
  import { useEffect, useState } from 'react';
  import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
  import { 
    LaunchDarklyToolbar,
    FlagOverridePlugin,
    EventInterceptionPlugin 
  } from '@launchdarkly/toolbar';

  // Create the plugin instances
  const flagOverridePlugin = new FlagOverridePlugin({
    storageNamespace: 'my-app-overrides', // Optional: customize storage key
  });
  const eventInterceptionPlugin = new EventInterceptionPlugin({
    eventCapacity: 250, // Maximum events to store (default: 150)
    enableLogging: true, // Console logging for debugging (default: false)
  });

  function App() {
    const [LDProvider, setLDProvider] = useState(null);

    useEffect(() => {
      const initializeLD = async () => {
        const Provider = await asyncWithLDProvider({
          clientSideID: 'enter-your-client-side-id',
          context: { key: 'example-context-key', name: 'Sandy Smith' },
          options: {
            // Pass the plugins to the SDK
            plugins: [flagOverridePlugin, eventInterceptionPlugin],
          },
        });
        setLDProvider(() => Provider);
      };

      initializeLD();
    }, []);

    if (!LDProvider) {
      return <div>Loading LaunchDarkly...</div>;
    }

    return (
      <LDProvider>
        <div>
          <h1>My App</h1>
          {/* Pass the same plugin instances to the toolbar */}
          <LaunchDarklyToolbar
            flagOverridePlugin={flagOverridePlugin}
            eventInterceptionPlugin={eventInterceptionPlugin}
          />
        </div>
      </LDProvider>
    );
  }
  ```
</CodeGroup>

### Set up dev server mode

If your team uses the LaunchDarkly CLI dev server, start it with CORS enabled:

<CodeGroup>
  ```bash title="Dev server with CORS enabled" lines wrap theme={null}
  ldcli dev-server start --project your-project --cors-enabled true
  ```
</CodeGroup>

Then connect the toolbar by passing in the URL of the CLI dev server:

<CodeGroup>
  ```tsx title="Connect the toolbar" lines wrap theme={null}
  import { LaunchDarklyToolbar } from '@launchdarkly/toolbar';

  function App() {
    return (
      <div>
        <h1>My App</h1>
        <LaunchDarklyToolbar devServerUrl="http://localhost:8765" />
      </div>
    );
  }
  ```
</CodeGroup>

## Properties

You can set the following properties to personalize the toolbar.

### Flag override plugin

The flag override plugin enables flag overrides and testing:

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`flagOverridePlugin`</td>
      <td>`IFlagOverridePlugin`</td>
      <td>`undefined`</td>
    </tr>
  </tbody>
</table>

### Event interception plugin

The event interception plugin enables **Events** tab functionality:

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`eventInterceptionPlugin`</td>
      <td>`IEventInterceptionPlugin`</td>
      <td>`undefined`</td>
    </tr>
  </tbody>
</table>

### Base LaunchDarkly URL

You can use the base LaunchDarkly URL for link generation, such as to create a missing feature flag:

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`baseUrl`</td>
      <td>`string` (optional)</td>
      <td>`https://app.launchdarkly.com`</td>
    </tr>
  </tbody>
</table>

### LaunchDarkly dev server URL

You can use the URL of your LaunchDarkly dev server to enable [dev server mode](#set-up-dev-server-mode):

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`devServerUrl`</td>
      <td>`string` (optional)</td>
      <td>`undefined`</td>
    </tr>
  </tbody>
</table>

### Toolbar position

You can set the toolbar position on your screen:

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`position`</td>
      <td>`top-left | top-right | bottom-left | bottom-right` (optional)</td>
      <td>`bottom-right`</td>
    </tr>
  </tbody>
</table>

### Project key

You can use a project key in multi-project setups (dev server mode only):

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`projectKey`</td>
      <td>`string` (optional)</td>
      <td>`undefined`</td>
    </tr>
  </tbody>
</table>

### Polling interval

You can set the polling interval for dev server updates (dev server mode only):

<table>
  <thead>
    <tr>
      <th>Prop</th>
      <th>Type</th>
      <th>Default</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`pollIntervalInMs`</td>
      <td>`number` (optional)</td>
      <td>`5000`</td>
    </tr>
  </tbody>
</table>

## Visibility control

The toolbar provides a global API for show/hide control:

<CodeGroup>
  ```js title="Visibility control" lines wrap theme={null}
  // Toggle visibility
  window.ldToolbar.toggle();

  // Enable/disable explicitly
  window.ldToolbar.enable();
  window.ldToolbar.disable();

  // Check current status
  window.ldToolbar.status(); // returns true/false
  ```
</CodeGroup>
