@disruptica/ladybug-react
v0.4.5
Published
React hooks and components for Ladybug embed widget
Maintainers
Readme
@disruptica/ladybug-react
React hooks and components for the Ladybug embed widget. Requires React ≥ 18.
Installation
npm install @disruptica/ladybug-react@disruptica/ladybug-react loads @disruptica/ladybug-widget for you, so consumers do not need to host widget.js or widget.esm.js themselves.
Usage
useLadybug hook
The primary hook for controlling the widget programmatically from any React component.
import { useLadybug } from '@disruptica/ladybug-react';
function SupportButton() {
const { open, close, toggle, isOpen, isReady, error } = useLadybug({
embedKey: 'emb_xxx',
position: 'bottom-right',
primaryColor: '#4f46e5',
mode: 'system',
showLauncher: false, // manage your own trigger
});
if (error) return <p>Failed to load widget</p>;
return (
<button onClick={toggle} disabled={!isReady}>
{isOpen ? 'Close chat' : 'Open chat'}
</button>
);
}<LadybugButton> component
A pre-styled pill button that loads and opens the widget on click.
import { LadybugButton } from '@disruptica/ladybug-react';
// Default appearance
<LadybugButton
embedKey="emb_xxx"
primaryColor="#4f46e5"
/>
// Custom label and position
<LadybugButton
embedKey="emb_xxx"
primaryColor="#10b981"
position="bottom-left"
launcherLabel="Get help"
>
Contact support
</LadybugButton><LadybugWidget> component (headless, controlled)
A renderless component for declarative control of the widget lifecycle. Useful when you want to integrate the open/close state into your own UI.
import { useState } from 'react';
import { LadybugWidget } from '@disruptica/ladybug-react';
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<LadybugWidget
embedKey="emb_xxx"
open={isOpen}
onOpenChange={setIsOpen}
showLauncher={false}
/>
<button onClick={() => setIsOpen((v) => !v)}>
{isOpen ? 'Close' : 'Open'} chat
</button>
</>
);
}Uncontrolled with built-in launcher
Mount <LadybugWidget> once (e.g. in your root layout) and it shows the floating launcher automatically.
// app/layout.tsx or _app.tsx
import { LadybugWidget } from '@disruptica/ladybug-react';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<LadybugWidget
embedKey="emb_xxx"
position="bottom-right"
primaryColor="#4f46e5"
/>
</body>
</html>
);
}Identifying logged-in users
Pass a signed token from your backend so Ladybug associates sessions with real users. Generate it with @disruptica/ladybug-identity.
// Static token fetched once
const { data: token } = useSWR('/api/ladybug-token', (url) =>
fetch(url).then((r) => r.json()).then((d) => d.token)
);
<LadybugWidget embedKey="emb_xxx" userToken={token} />
// Dynamic provider (called by the widget on demand)
<LadybugWidget
embedKey="emb_xxx"
getUserToken={async () => {
const res = await fetch('/api/ladybug-token');
const { token } = await res.json();
return token;
}}
/>API reference
useLadybug(config)
| Return value | Type | Description |
|---|---|---|
| open | () => void | Open the widget |
| close | () => void | Close the widget |
| toggle | () => void | Toggle the widget |
| isOpen | boolean | Whether the widget is currently open |
| isReady | boolean | Whether the widget runtime is ready |
| error | Error \| null | Script load error, if any |
Config options
| Option | Type | Default | Description |
|---|---|---|---|
| embedKey | string | required | Your embed key (emb_xxx) |
| position | "bottom-right" \| "bottom-left" | "bottom-right" | Launcher position |
| launcherLabel | string | "Request a change" | Button label |
| primaryColor | string | "#4f46e5" | Hex accent color |
| mode | "light" \| "dark" \| "system" | "system" | Color mode |
| showLauncher | boolean | true | Show the floating launcher |
| userToken | string | — | Signed identity token |
| getUserToken | () => Promise<string \| null> | — | Async token provider |
License
MIT
