@@ -32,14 +32,14 @@ instantiating it will keep it disabled in production environments.
3232
3333The Developer Toolbar depends on your LaunchDarkly JS client having a reference to the same ` FlagOverridePlugin ` and
3434` EventInterceptionPlugin ` that you pass into the Developer Toolbar. As such, ensure that you instantiate the Developer Toolbar at the same time or immediately after the LaunchDarkly JS client is instantiated.
35- Below are a few examples on how to instantiate the toolbar, one using the ` useLaunchDarklyToolbar ` react hook, and one using the CDN hosted toolbar script.
3635
37- ### React Hook (Recommended for React Applications)
36+ ### React Hook
3837
3938``` tsx
4039import { render } from ' react-dom' ;
4140import { asyncWithLDProvider } from ' launchdarkly-react-client-sdk' ;
42- import { useLaunchDarklyToolbar , FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar' ;
41+ import { useLaunchDarklyToolbar } from ' @launchdarkly/toolbar/react' ;
42+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
4343
4444const flagOverridePlugin = new FlagOverridePlugin ();
4545const eventInterceptionPlugin = new EventInterceptionPlugin ();
@@ -90,9 +90,118 @@ const eventInterceptionPlugin = new EventInterceptionPlugin();
9090})();
9191```
9292
93- ### CDN Script Tag (Framework-Agnostic)
93+ ### Vue Composable
9494
95- Works with any JavaScript framework (Vue, Angular, Svelte, vanilla JS, etc.). Add this script to your ` index.html ` file.
95+ ``` typescript
96+ import { onMounted } from ' vue' ;
97+ import * as LDClient from ' launchdarkly-js-client-sdk' ;
98+ import { useLaunchDarklyToolbar } from ' @launchdarkly/toolbar/vue' ;
99+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
100+
101+ const flagOverridePlugin = new FlagOverridePlugin ();
102+ const eventInterceptionPlugin = new EventInterceptionPlugin ();
103+
104+ // Initialize LaunchDarkly client
105+ const client = LDClient .initialize (
106+ ' client-side-id-123abc' ,
107+ {
108+ kind: ' user' ,
109+ key: ' user-key-123abc' ,
110+ name: ' Sandy Smith' ,
111+ email: ' sandy@example.com' ,
112+ },
113+ {
114+ plugins: [flagOverridePlugin , eventInterceptionPlugin ],
115+ },
116+ );
117+
118+ // In your Vue component or setup function
119+ export default {
120+ setup() {
121+ onMounted (async () => {
122+ await client .waitForInitialization ();
123+ });
124+
125+ // Initialize toolbar with the same plugin instances
126+ useLaunchDarklyToolbar ({
127+ flagOverridePlugin ,
128+ eventInterceptionPlugin ,
129+
130+ // OR Dev Server Mode
131+ devServerUrl: ' http://localhost:8080' ,
132+ projectKey: ' my-project' ,
133+
134+ position: ' bottom-right' ,
135+ enabled: import .meta .env .DEV , // Vite
136+ // enabled: process.env.NODE_ENV === 'development', // Webpack
137+ });
138+
139+ return {
140+ // your component data
141+ };
142+ },
143+ };
144+ ```
145+
146+ ### Angular Service
147+
148+ ``` typescript
149+ import { Component , OnInit } from ' @angular/core' ;
150+ import * as LDClient from ' launchdarkly-js-client-sdk' ;
151+ import LaunchDarklyToolbarService from ' @launchdarkly/toolbar/angular' ;
152+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
153+ import { environment } from ' ../environments/environment' ;
154+
155+ @Component ({
156+ selector: ' app-root' ,
157+ template: ` <router-outlet></router-outlet> ` ,
158+ providers: [LaunchDarklyToolbarService ],
159+ })
160+ export class AppComponent implements OnInit {
161+ private flagOverridePlugin = new FlagOverridePlugin ();
162+ private eventInterceptionPlugin = new EventInterceptionPlugin ();
163+ private ldClient: LDClient .LDClient ;
164+
165+ constructor (private toolbarService : LaunchDarklyToolbarService ) {
166+ // Initialize LaunchDarkly client
167+ this .ldClient = LDClient .initialize (
168+ ' client-side-id-123abc' ,
169+ {
170+ kind: ' user' ,
171+ key: ' user-key-123abc' ,
172+ name: ' Sandy Smith' ,
173+ email: ' sandy@example.com' ,
174+ },
175+ {
176+ plugins: [this .flagOverridePlugin , this .eventInterceptionPlugin ],
177+ },
178+ );
179+ }
180+
181+ async ngOnInit() {
182+ await this .ldClient .waitForInitialization ();
183+
184+ // Initialize toolbar with the same plugin instances
185+ if (! environment .production ) {
186+ await this .toolbarService .initialize ({
187+ flagOverridePlugin: this .flagOverridePlugin ,
188+ eventInterceptionPlugin: this .eventInterceptionPlugin ,
189+
190+ // OR Dev Server Mode
191+ devServerUrl: ' http://localhost:8080' ,
192+ projectKey: ' my-project' ,
193+
194+ position: ' bottom-right' ,
195+ enabled: true ,
196+ });
197+ }
198+ }
199+ }
200+ ```
201+
202+ ### CDN Script Tag
203+
204+ Works with any JavaScript framework or vanilla JS. Add this script to your ` index.html ` file.
96205
97206``` html
98207<script src =" https://unpkg.com/@launchdarkly/toolbar@latest/cdn/toolbar.min.js" ></script >
@@ -150,6 +259,32 @@ declare global {
150259}
151260```
152261
262+ ## Framework Support
263+
264+ The toolbar provides first-class support for popular frameworks:
265+
266+ ### Import Paths
267+
268+ ``` typescript
269+ // Core toolbar (for CDN or vanilla JS)
270+ import { init } from ' @launchdarkly/toolbar' ;
271+
272+ // Plugins (framework-agnostic)
273+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
274+
275+ // React hook
276+ import { useLaunchDarklyToolbar } from ' @launchdarkly/toolbar/react' ;
277+
278+ // Vue composable
279+ import { useLaunchDarklyToolbar } from ' @launchdarkly/toolbar/vue' ;
280+
281+ // Angular service
282+ import LaunchDarklyToolbarService from ' @launchdarkly/toolbar/angular' ;
283+
284+ // TypeScript types
285+ import type { InitializationConfig } from ' @launchdarkly/toolbar/types' ;
286+ ```
287+
153288## Package Structure
154289
155290```
@@ -161,19 +296,27 @@ declare global {
161296│ │ ├── ui/ # UI components (Toolbar, Tabs, List, etc.)
162297│ │ ├── tests/ # Unit tests
163298│ │ └── index.ts # Core entry point (for CDN builds)
164- │ ├── react/ # React-specific integrations and utilities
299+ │ ├── react/ # React hook and utilities
165300│ │ ├── useLaunchDarklyToolbar.ts # Main React hook
166301│ │ └── lazyLoadToolbar.ts # Dynamic CDN loading
302+ │ ├── vue/ # Vue composable
303+ │ │ └── useLaunchDarklyToolbar.ts # Main Vue composable
304+ │ ├── angular/ # Angular service
305+ │ │ └── launchdarkly-toolbar.service.ts # Injectable service
167306│ ├── types/ # TypeScript type definitions
168307│ │ ├── config.ts # Configuration types
169308│ │ ├── events.ts # Event types
170309│ │ ├── plugins.ts # Plugin interfaces
171310│ │ └── index.ts # Type exports
172311│ └── index.ts # Main entry point (NPM package)
173312├── dist/ # NPM package output
174- │ ├── index.js # ES module build
175- │ ├── index.cjs # CommonJS build
176- │ └── index.d.ts # TypeScript definitions
313+ │ ├── js/ # ES module builds
314+ │ │ ├── index.js
315+ │ │ ├── react.js
316+ │ │ ├── vue.js
317+ │ │ └── angular.js
318+ │ ├── *.cjs # CommonJS builds
319+ │ └── *.d.ts # TypeScript definitions
177320├── cdn/ # CDN bundle output
178321│ └── toolbar.min.js # IIFE bundle for script tags
179322├── .storybook/ # Storybook configuration
@@ -203,7 +346,9 @@ interface ToolbarConfig {
203346}
204347```
205348
206- ### React Hook Options
349+ ### Framework-Specific Options
350+
351+ All framework integrations (React, Vue, Angular) support the same configuration options:
207352
208353``` typescript
209354interface UseLaunchDarklyToolbarConfig extends ToolbarConfig {
@@ -212,12 +357,39 @@ interface UseLaunchDarklyToolbarConfig extends ToolbarConfig {
212357}
213358```
214359
360+ ** Example for local development:**
361+
362+ ``` typescript
363+ // React
364+ useLaunchDarklyToolbar ({
365+ toolbarBundleUrl: ' http://localhost:5764/toolbar.min.js' ,
366+ enabled: process .env .NODE_ENV === ' development' ,
367+ // ... other options
368+ });
369+
370+ // Vue
371+ useLaunchDarklyToolbar ({
372+ toolbarBundleUrl: ' http://localhost:5764/toolbar.min.js' ,
373+ enabled: import .meta .env .DEV ,
374+ // ... other options
375+ });
376+
377+ // Angular
378+ await toolbarService .initialize ({
379+ toolbarBundleUrl: ' http://localhost:5764/toolbar.min.js' ,
380+ enabled: ! environment .production ,
381+ // ... other options
382+ });
383+ ```
384+
215385## Modes
216386
217387### Dev Server Mode
218388
219389Connect directly to a LaunchDarkly dev server to manage server-side flags:
220390
391+ ** React:**
392+
221393``` tsx
222394useLaunchDarklyToolbar ({
223395 devServerUrl: ' http://localhost:5764' ,
@@ -226,12 +398,32 @@ useLaunchDarklyToolbar({
226398});
227399```
228400
229- or if you are using the CDN script:
401+ ** Vue:**
402+
403+ ``` typescript
404+ useLaunchDarklyToolbar ({
405+ devServerUrl: ' http://localhost:5764' ,
406+ projectKey: ' my-project' ,
407+ position: ' bottom-right' ,
408+ });
409+ ```
410+
411+ ** Angular:**
412+
413+ ``` typescript
414+ await toolbarService .initialize ({
415+ devServerUrl: ' http://localhost:5764' ,
416+ projectKey: ' my-project' ,
417+ position: ' bottom-right' ,
418+ });
419+ ```
420+
421+ ** CDN:**
230422
231423``` typescript
232424window .LaunchDarklyToolbar .init ({
233- devServerUrl: ' http://localhost:8080 ' ,
234- projectKey: ' my-project' , // Optional
425+ devServerUrl: ' http://localhost:5764 ' ,
426+ projectKey: ' my-project' ,
235427 position: ' bottom-right' ,
236428});
237429```
@@ -245,19 +437,54 @@ window.LaunchDarklyToolbar.init({
245437
246438### SDK Mode
247439
248- Integrate with LaunchDarkly React SDK for client-side flag management:
440+ Integrate with LaunchDarkly JS SDK for client-side flag management:
441+
442+ ** React:**
249443
250444``` tsx
251- import { useFlagOverridePlugin , useEventInterceptionPlugin } from ' ./plugins' ;
445+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
446+
447+ const flagOverridePlugin = new FlagOverridePlugin ();
448+ const eventInterceptionPlugin = new EventInterceptionPlugin ();
449+
450+ useLaunchDarklyToolbar ({
451+ flagOverridePlugin ,
452+ eventInterceptionPlugin ,
453+ position: ' bottom-right' ,
454+ });
455+ ```
456+
457+ ** Vue:**
458+
459+ ``` typescript
460+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
461+
462+ const flagOverridePlugin = new FlagOverridePlugin ();
463+ const eventInterceptionPlugin = new EventInterceptionPlugin ();
252464
253465useLaunchDarklyToolbar ({
254- flagOverridePlugin: useFlagOverridePlugin (),
255- eventInterceptionPlugin: useEventInterceptionPlugin (),
466+ flagOverridePlugin ,
467+ eventInterceptionPlugin ,
468+ position: ' bottom-right' ,
469+ });
470+ ```
471+
472+ ** Angular:**
473+
474+ ``` typescript
475+ import { FlagOverridePlugin , EventInterceptionPlugin } from ' @launchdarkly/toolbar/plugins' ;
476+
477+ const flagOverridePlugin = new FlagOverridePlugin ();
478+ const eventInterceptionPlugin = new EventInterceptionPlugin ();
479+
480+ await toolbarService .initialize ({
481+ flagOverridePlugin ,
482+ eventInterceptionPlugin ,
256483 position: ' bottom-right' ,
257484});
258485```
259486
260- or if you are using the CDN script:
487+ ** CDN: **
261488
262489``` typescript
263490window .LaunchDarklyToolbar .init ({
0 commit comments