Documentation

Embed The Shell

The shell is hosted by Duct and embedded as an iframe. The SDK gives React and Next.js projects a typed wrapper, while plain JavaScript apps can use the postMessage protocol directly.

React / Next.js

Install the SDK and mount the shell once near your app layout.

bash
npm install @duct-sdk/sdk
tsx
'use client';

Appearance & Sizing

The launcher and panel are controlled by a few DuctShell props. You can also set these in duct.config.ts under widget so they apply everywhere without code changes.

preset
"tall" (vertical rectangle, default), "square" (Copilot-style), or "large". Sets the panel size/shape. Overrides any raw width/height.
position
"bottom-right" (default) or "bottom-left". The starting corner only — users can drag the bubble anywhere, and move the opened panel via its top handle.
theme
"system" (default), "light", or "dark". Controls the launcher bubble chrome; the chat surface also honors widget.theme.
draggable
true by default. The bubble and opened panel are draggable; the bubble position persists per shell in localStorage. Set false to pin them.
panelWidth / panelHeight
Optional pixel overrides used only when preset is not set.

Presets keep things responsive

Preset dimensions are automatically capped to the viewport (min(size, 100vw/100dvh - margins)), so the panel never overflows on smaller screens. For phones, prefer the standalone page (below).

Conversation persistence

The shell iframe stores session ID and message history in browser storage on the shell host origin, keyed by shell ID, so conversations resume after parent-page navigation. Dashboard playground Human mode uses a separate storage namespace — it does not share chat state with your embedded shell on the same browser, even for the same shell ID. Launcher bubble position is stored on your site's origin (DuctShell on the parent page), not inside the iframe.

Plain JavaScript

If you are not using React, embed the iframe and respond to token requests.

html
<div id="duct-root"></div>

Token Endpoint

The shell calls this endpoint when it needs to invoke an authenticated action for the current user.

ts
import { NextResponse } from 'next/server';

Security notes

Validate event.origin and event.source when using a manual iframe. Never put your Duct secret key in client-side JavaScript; token generation belongs on your server.

Mobile and Standalone

For small screens, route users to the standalone shell page instead of a floating iframe: https://shell.ductai.vercel.app/standalone/{shellId}.