Chat Renderer API

Import the inline chat-renderer contract from @theaiplatform/miniapp-sdk/chat-renderer. A ui.renderer contribution uses this entry point to render the payload of an exact same-package chat.block. The two contributions must declare the same locked payload schema, and the renderer must cover every target selected by the chat block.

The host mounts the renderer in a bounded, SDK-bridge-free sandboxed frame. The mount context contains the immutable block payload, cosmetic theme state, and only the actions and resources admitted by the signed renderer contribution. It does not expose ambient navigation, tools, storage, events, frames, or network access.

Mount an Inline Renderer

Default-export a TapFederatedChatRendererModule. Its mount method receives the host-owned container and one TapFederatedChatRendererMountContext. Return a TapFederatedChatRendererMount when the renderer has cleanup work.

import type { TapFederatedChatRendererModule } from '@theaiplatform/miniapp-sdk/chat-renderer';

type Preview = Readonly<{ title: string; nodeId: string }>;

const renderer: TapFederatedChatRendererModule<Preview> = {
  mount(container, context) {
    const button = document.createElement('button');
    button.textContent = context.payload.title;
    button.onclick = () => context.actions['open-canvas']?.invoke('/nodeId');
    container.replaceChildren(button);

    return {
      unmount() {
        button.onclick = null;
        container.replaceChildren();
      },
    };
  },
};

export default renderer;

Validate the payload against the package-owned locked schema before using it. Remove every listener, subscription, pending view update, and rendered node in unmount. A missing release, provenance or schema mismatch, load failure, crash, or invalid renderer message leaves the host-sealed static fallback in place.

Live Theme

TapFederatedChatRendererTheme exposes the current TapFederatedChatRendererThemeValue and a subscription. Apply the initial snapshot, subscribe for later changes, and remove the subscription during unmount. Theme state is cosmetic and conveys no host authority.

const applyTheme = () => {
  root.dataset.theme = context.theme.getSnapshot();
};

applyTheme();
const stopTheme = context.theme.subscribe(applyTheme);
// Call stopTheme() during unmount.

Declared Actions

Each TapFederatedChatRendererAction is a host-authorized action admitted by the signed contribution. Look it up by its declared ID. invoke accepts only an optional RFC 6901 pointer into the host-sealed payload, so renderer-authored values cannot become navigation targets.

openButton.onclick = () => {
  context.actions['open-canvas']?.invoke('/nodeId');
};

Treat a missing action as unavailable. The host remains responsible for authorization and rejects a pointer that does not resolve inside the sealed payload.

Declared Resources

TapFederatedChatRendererResources resolves same-origin resources admitted by the contribution without using postMessage. Read by declared resource ID; the host fetches each ID at most once during a mount and returns a read-only value.

const summary = await context.resources.read<{
  caption: string;
}>('selected-node-summary');

caption.textContent = summary.caption;

Validate resource data before rendering it, and ignore any asynchronous result that settles after unmount.

Public Export Contract

ExportPurposeInputs and resultLifecycle and errorsWorking example
TapFederatedChatRendererThemeValueRestricts the host-selected renderer theme to light or dark.Supplies one light or dark string from the live theme snapshot.Type only; theme changes are cosmetic and never grant authority.Live theme
TapFederatedChatRendererThemeExposes the current renderer theme and later theme changes.getSnapshot returns a theme value and subscribe returns cleanup.The value can change while mounted; remove every subscription during unmount.Live theme
TapFederatedChatRendererActionRepresents one host-authorized action admitted by the contribution.Exposes an ID, label, and invoke with an optional sealed-payload pointer.Missing actions are unavailable; invalid payload pointers fail closed.Declared actions
TapFederatedChatRendererResourcesResolves host-authorized same-origin resources for the renderer.read accepts a declared resource ID and resolves a read-only typed value.Each ID is fetched at most once per mount; ignore results that arrive after cleanup.Declared resources
TapFederatedChatRendererMountContextSupplies exact package identity and the renderer's least-authority inputs.Contains immutable identity, payload, theme, action, and resource fields.The context belongs to one mount and must not be retained after unmount.Mount an inline renderer
TapFederatedChatRendererMountDefines the optional cleanup handle returned by a renderer mount.Contains an unmount function that returns void or a promise.Cleanup removes all renderer-owned subscriptions, handlers, work, and rendered nodes.Mount an inline renderer
TapFederatedChatRendererModuleDefines the default module exported by a chat-renderer target.mount receives an element and typed context, then returns optional cleanup.The host mounts lazily and keeps the sealed static fallback when rendering fails.Mount an inline renderer