Skip to content
kitn AI/UI

Docked assistant

Pin a help assistant to the side of your app as a permanent, full-height column — always open, no launcher to find. The panel sits beside the scrolling page; because <kai-chat> lives in its own Shadow DOM, the host’s CSS stays out and the panel’s styles stay in. Scroll the host below, toggle its light/dark, and ask about billing.

A docked panel keeps the assistant in view the whole session — well suited to dashboards, admin consoles, and support tools where users return to it constantly. A floating launcher (the Support widget) stays out of the way until summoned, which fits marketing pages and content sites where chat is occasional.

Docked panelFloating widget
VisibilityAlways openToggled by a button
Layout costReserves a columnOverlays the page
Best forApps, dashboards, consolesSites, docs, landing pages

Give the page a flex (or grid) row: the app content takes the remaining width and scrolls on its own, and a fixed-width <kai-chat> fills a full-height column on the right.

<div class="layout">
<main id="content"><!-- your app --></main>
<aside id="dock">
<kai-chat id="assistant" chat-title="Support" prose-size="sm"></kai-chat>
</aside>
</div>
<script type="module">
import '@kitn.ai/ui/elements';
const chat = document.getElementById('assistant');
chat.suggestions = ['How do I change my plan?', 'Where are my invoices?'];
chat.addEventListener('kai-submit', (e) => {
const text = e.detail.value;
/* stream your reply back into chat.messages (see Drop-in chat) */
});
</script>
.layout { display: flex; height: 100vh; }
#content { flex: 1; min-width: 0; overflow-y: auto; }
#dock { width: 360px; flex-shrink: 0; height: 100%; border-left: 1px solid rgb(0 0 0 / 0.1); }
#dock kai-chat { display: block; height: 100%; }

The panel reads 100% of its column, so it stays full-height as the content beside it scrolls independently.

Drive the panel’s theme attribute from your app’s own theme state — set it on mount and update it whenever the user toggles light/dark, so the dock always matches the page around it.

const setTheme = (mode) => chat.setAttribute('theme', mode); // 'light' | 'dark'
themeToggle.addEventListener('click', () => setTheme(isDark() ? 'dark' : 'light'));
  • Support widget — the floating-launcher counterpart for sites that don’t dock.
  • Drop-in chat — the streaming loop this panel uses on kai-submit.
  • Theming — match the panel to your brand.
  • kai-chat referencesuggestions, proseSize, slashCommands, and more.