Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions docs/guides/authoring-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,77 @@ 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
Copy link
Copy Markdown
Collaborator

@ditman ditman May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this!

I think the angular renderer needs a level-3 title as well so the structure ends up as:

## 3. Registering with the Renderers (Client)

... probably nothing here, or a short intro ...

### Angular renderer

... instructions for angular ...

### Lit v0.9

... instructions for lit 0.9...

### Lit v0.8 (legacy)

...

What do you think @zeroasterisk?


#### 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 {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<LitComponentApi>(
'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<LitComponentApi>([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 `<a2ui-surface>` element by setting `enableCustomElements = true`.

```typescript
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);
Comment thread
shahabl marked this conversation as resolved.
```

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; // 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`.

---

## 4. Invoking from the Agent
Expand Down