Skip to content
kitn AI/UI

Artifact

kai-artifact

Show an AI-generated deliverable beside the conversation — a web page, doc, image, or PDF — in a sandboxed iframe with a nav toolbar and a switchable Code view.

  • Shadow DOM
  • Sandboxed iframe
  • Preview + Code tabs
  • Configurable toolbar
  • 4 events

Point src at your hosted artifact and set files in JavaScript (it’s an array, so it can’t be an HTML attribute) for the Code tab.

<kai-artifact src="https://your.app/artifacts/abc/index.html" style="display:block;height:520px"></kai-artifact>
<script type="module">
import '@kitn.ai/ui/elements';
await customElements.whenDefined('kai-artifact');
const el = document.querySelector('kai-artifact');
el.files = [
{ path: 'index.html', url: '…/index.html', type: 'html', code: '<!DOCTYPE …>' },
{ path: 'styles.css', url: '…/styles.css', type: 'other', language: 'css', code: '' },
];
el.addEventListener('kai-navigate', (e) => console.log(e.detail.url));
</script>
  • files — each entry needs a path; add url for the preview, code + language for the Code tab, and type (html | pdf | image | other). Folders come from the / in paths.
  • Toolbar — hide any default control with its no-* flag (no-nav, no-reload, no-home, no-path-field, no-tabs); expandable and open-in-tab are opt-in.
  • Sandbox defaults to allow-scripts allow-forms. Widen it only for trusted content.

Hide the whole toolbar for a chrome-free embedded tile.

Rounded, bordered chrome for an artifact rendered outside a panel — a modal or inline tile.

An expand-to-fill button that fires kai-maximize-change, plus the open-in-tab control.

PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
srcURL the preview iframe frames. Consumer-controlled.
files[]Files for the Code tab tree + each file's preview `url`. Omit for a preview-only artifact (the Code tab then has nothing to show; pair it with `no-tabs` to hide the toggle). Set as a JS property (array).
tabControlled active tab: `preview` or `code`. When set, the artifact follows it (re-asserted on change). Leave unset for an uncontrolled tab (see `defaultTab`).
defaultTabUncontrolled INITIAL tab (used only when `tab` is unset). Default `preview`. Seeds the starting tab; the user can then switch freely without the consumer re-asserting a controlled `tab`.
activeFileSelected file path. Syncs the tree highlight, Code source, and preview.
sandbox'allow-scripts allow-forms'iframe `sandbox` override. Secure default `allow-scripts allow-forms` (NOT `allow-same-origin`).
iframeTitleAccessible title for the preview iframe.
maximizedfalseReflects the artifact's own maximized view-state (usually driven by the protocol).
expandablefalseShow the expand-to-fill button (OPT-IN).
openInTabfalseShow the open-in-new-tab button (OPT-IN).
noNavfalseHide back/forward.
noReloadfalseHide reload.
noHomefalseHide home.
noPathFieldfalseHide the address field.
noTabsfalseHide the Preview|Code toggle.
standalonefalseStandalone chrome: rounded corners + border (else square, borderless in-panel).
readonlyPathfalseShow the address but make it read-only (visible, nav-tracking, non-editable).
displayUrlFriendly address shown in the path field instead of the real current url (read-only, non-navigable). Use when the framed url is not consumer-facing (e.g. a `data:` blob) so a clean address shows instead of leaking it. Scalar string: set as the `display-url` attribute or the `displayUrl` property.
EventDetailNotes
Fired when a file is selected. `detail.path`.
Artifact's own maximize button toggled (consumer-observable; non-bubbling).
The maximize PROTOCOL intent, raised as a raw bubbling + composed CustomEvent (not through `dispatch`) so an enclosing `<kai-resizable>` can catch it and maximize the containing panel. Declared here so it is typed and reaches the generated API. Listen for it to drive maximize from your own chrome, or re-emit it to trigger one.
Fired when the preview navigates. `detail.url` = the new location.
Fired when the Preview|Code tab changes. `detail.tab`.
MethodSignatureNotes
(): voidGo back in the artifact's own history stack (no-op when there's no prior entry).
(): voidGo forward in the history stack (no-op when there's no forward entry).
(): voidForce-reload the current preview url (also re-renders an inline PDF).
(): voidNavigate to the `src` home url (no-op when there's no `src`).
(url: string): voidPush + load a url in the preview, the path-field submit path (fires kai-navigate).
(path: string): voidSelect a file by path: highlights the tree, shows its source, navigates the preview (fires kai-file-select + kai-navigate). Named selectFile to avoid the `activeFile` prop.
(): voidOpen the current url in a new browser tab (no-op when there's no concrete url). Named openExternal, NOT openInTab, which is a prop (toolbar button visibility).
(): voidEnter the maximized view-state (fires kai-maximize-change{maximized:true}). Named maximize, NOT maximized, which is a prop.
(): voidExit the maximized view-state (fires kai-maximize-change{maximized:false}).

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

Artifact