From d32de4da7298b5327e4de67f29416ad0323e206d Mon Sep 17 00:00:00 2001 From: Shahab Layeghi Date: Wed, 13 May 2026 13:13:24 -0700 Subject: [PATCH 1/2] docs: add Lit custom component registration guide for v0.9 and v0.8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document how to register custom components with the Lit renderer in both protocol versions. The v0.9 path (Catalog + MessageProcessor + catalogId) is documented as the primary approach. The v0.8 path (componentRegistry + enableCustomElements) is documented as legacy. The enableCustomElements property on Surface was easy to discover as a footgun — custom components silently don't render if the flag is not set before the surface/processor properties. --- docs/guides/authoring-components.md | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/docs/guides/authoring-components.md b/docs/guides/authoring-components.md index 6d6aa4e98..48987879d 100644 --- a/docs/guides/authoring-components.md +++ b/docs/guides/authoring-components.md @@ -179,6 +179,76 @@ Key points for registration: - **Lazy Loading**: Use `import()` to lazy-load the component code. - **Input Bindings**: Use `inputBinding` to map properties from the schema to Angular inputs. +### Registering with the Lit Renderer + +#### v0.9 (recommended) + +With `@a2ui/lit/v0_9`, catalog registration is handled at the protocol level. Define a `Catalog` object with your components and pass it to the `MessageProcessor`. When the agent sends a `createSurface` message with a matching `catalogId`, the processor automatically resolves and binds your catalog — no client-side flags required. + +```typescript +import {z} from 'zod'; +import {Catalog, MessageProcessor} from '@a2ui/web_core/v0_9'; +import {A2uiLitElement, basicCatalog} from '@a2ui/lit/v0_9'; +import type {LitComponentApi} from '@a2ui/lit/v0_9'; + +// 1. Define your component's API using a Zod schema +const MyChartApi = { + name: 'MyChart', + tagName: 'my-chart', // your custom element tag + schema: z.object({ + title: z.string().optional(), + data: z.array(z.object({label: z.string(), value: z.number()})), + }), +} satisfies LitComponentApi; + +// 2. Create a named catalog containing your component(s) +const myCatalog = new Catalog( + 'mycompany.com:my-catalog', // must match what the agent sends in createSurface.catalogId + [MyChartApi], +); + +// 3. Register it with the MessageProcessor alongside any other catalogs you support +const processor = new MessageProcessor([basicCatalog, myCatalog]); +``` + +The agent then selects your catalog by referencing its ID in the `createSurface` message: + +```json +{ + "version": "v0.9", + "createSurface": { + "surfaceId": "main", + "catalogId": "mycompany.com:my-catalog" + } +} +``` + +The `A2uiSurface` element in v0.9 receives a fully-resolved `SurfaceModel` (with catalog already bound), so custom components render automatically alongside standard ones. + +#### v0.8 (legacy) + +When using the `@a2ui/lit` renderer with the v0.8 protocol, register your custom components via the `componentRegistry`, then opt in on the `` element by setting `enableCustomElements = true`. + +```typescript +import {v0_8 as a2uiModule} from '@a2ui/lit'; + +// Register custom components in the component registry +a2uiModule.componentRegistry.register('MyChart', MyChartElement); +``` + +Then set `enableCustomElements = true` on the surface element **before** assigning `surface` and `processor`, so the flag is active on the first render pass: + +```typescript +const surfaceElement = document.querySelector('a2ui-surface'); + +surfaceElement.enableCustomElements = true; // must come first +surfaceElement.surfaceId = 'main'; +surfaceElement.surface = surface; +surfaceElement.processor = processor; +``` + +> **Note:** Without `enableCustomElements = true`, custom components will not render even if they are properly registered, because the flag defaults to `false`. + --- ## 4. Invoking from the Agent From 5219e15c256d3257511c8772ddcd7672bbe075c6 Mon Sep 17 00:00:00 2001 From: Shahab Layeghi Date: Wed, 13 May 2026 15:42:05 -0700 Subject: [PATCH 2/2] docs: address review comments on Lit registration guide - Remove unused A2uiLitElement import from v0.9 snippet - Add clarifying comment that MyChartElement is the user's Lit component class - Add inline comments for surface and processor variables in v0.8 snippet --- docs/guides/authoring-components.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/guides/authoring-components.md b/docs/guides/authoring-components.md index 48987879d..ff4eec261 100644 --- a/docs/guides/authoring-components.md +++ b/docs/guides/authoring-components.md @@ -188,7 +188,7 @@ With `@a2ui/lit/v0_9`, catalog registration is handled at the protocol level. De ```typescript import {z} from 'zod'; import {Catalog, MessageProcessor} from '@a2ui/web_core/v0_9'; -import {A2uiLitElement, basicCatalog} from '@a2ui/lit/v0_9'; +import {basicCatalog} from '@a2ui/lit/v0_9'; import type {LitComponentApi} from '@a2ui/lit/v0_9'; // 1. Define your component's API using a Zod schema @@ -233,6 +233,7 @@ When using the `@a2ui/lit` renderer with the v0.8 protocol, register your custom import {v0_8 as a2uiModule} from '@a2ui/lit'; // Register custom components in the component registry +// MyChartElement is your Lit component class (extends LitElement) a2uiModule.componentRegistry.register('MyChart', MyChartElement); ``` @@ -243,8 +244,8 @@ const surfaceElement = document.querySelector('a2ui-surface'); surfaceElement.enableCustomElements = true; // must come first surfaceElement.surfaceId = 'main'; -surfaceElement.surface = surface; -surfaceElement.processor = processor; +surfaceElement.surface = surface; // the SurfaceModel instance +surfaceElement.processor = processor; // the A2uiMessageProcessor instance ``` > **Note:** Without `enableCustomElements = true`, custom components will not render even if they are properly registered, because the flag defaults to `false`.