Wrapper surface
The default shell of <AparteChat> leaves you these places to put your own markup. The
same slots exist on all four wrappers — that is checked mechanically on every pnpm gate,
not promised in prose — and each framework declares them in its own idiom.
| Slot | React | Vue | Svelte | Angular |
|---|---|---|---|---|
composer | composer={…} | <template #composer> | <svelte:fragment slot="composer"> | slot="composer" |
empty-state | emptyState={…} | <template #empty-state> | <svelte:fragment slot="empty-state"> | slot="empty-state" |
above-composer | aboveComposer={…} | <template #above-composer> | <svelte:fragment slot="above-composer"> | slot="above-composer" |
toolbar | toolbar={…} | <template #toolbar> | <svelte:fragment slot="toolbar"> | slot="toolbar" |
What each one is for
Section titled “What each one is for”composer
Section titled “composer”Custom composer content, rendered inside <aparte-composer> in place of the default shell (input · send, plus the attachment primitives when attachments is set).
React:
<AparteChat composer={<MyThing />} />Vue:
<AparteChat> <template #composer><MyThing /></template></AparteChat>Svelte:
<AparteChat> <svelte:fragment slot="composer"><MyThing /></svelte:fragment></AparteChat>Angular:
<aparte-chat> <div slot="composer"><app-my-thing /></div></aparte-chat>empty-state
Section titled “empty-state”Welcome / placeholder content shown INSIDE the viewport while there are no messages (a real “empty state” region, not a workaround via aboveComposer).
React:
<AparteChat emptyState={<MyThing />} />Vue:
<AparteChat> <template #empty-state><MyThing /></template></AparteChat>Svelte:
<AparteChat> <svelte:fragment slot="empty-state"><MyThing /></svelte:fragment></AparteChat>Angular:
<aparte-chat> <div slot="empty-state"><app-my-thing /></div></aparte-chat>above-composer
Section titled “above-composer”Content rendered ABOVE the composer (e.g. a disclaimer banner, a “scroll to bottom” affordance, a context chip).
React:
<AparteChat aboveComposer={<MyThing />} />Vue:
<AparteChat> <template #above-composer><MyThing /></template></AparteChat>Svelte:
<AparteChat> <svelte:fragment slot="above-composer"><MyThing /></svelte:fragment></AparteChat>Angular:
<aparte-chat> <div slot="above-composer"><app-my-thing /></div></aparte-chat>toolbar
Section titled “toolbar”The composer’s bottom row — a mode picker, a model selector, a token counter.
React:
<AparteChat toolbar={<MyThing />} />Vue:
<AparteChat> <template #toolbar><MyThing /></template></AparteChat>Svelte:
<AparteChat> <svelte:fragment slot="toolbar"><MyThing /></svelte:fragment></AparteChat>Angular:
<aparte-chat> <div slot="toolbar"><app-my-thing /></div></aparte-chat>Callbacks
Section titled “Callbacks”The same six events on all four wrappers, each in its own idiom. React, Vue and Angular
hand you the payload directly; Svelte re-wraps it in a CustomEvent, so read it from
event.detail there.
| Payload | React | Vue | Svelte | Angular |
|---|---|---|---|---|
AparteSendEventDetail | onMessageSent | @message-sent | on:messageSent | (messageSent) |
AparteActionEventDetail | onAction | @action | on:action | (action) |
AparteMessage[] | onMessagesChange | @messages-change | on:messagesChange | (messagesChange) |
AparteMessage | onMessageAppended | @message-appended | on:messageAppended | (messageAppended) |
boolean | onTypingChange | @typing-change | on:typingChange | (typingChange) |
string | onConversationCreated | @conversation-created | on:conversationCreated | (conversationCreated) |
What each callback is for
Section titled “What each callback is for”messageSent
Section titled “messageSent”Notification that the user submitted a message from the composer.
action
Section titled “action”Fired when a custom bubble action (registered via aparteGlobalConfig.registerAction with zones: ['bubble']) is clicked — a typed wrapper over the bubbling aparte-action DOM event.
messagesChange
Section titled “messagesChange”Fired when the active message path changes (branch navigation / edit / retry / streaming).
messageAppended
Section titled “messageAppended”Fired when a message is appended internally (e.g. by AparteClient).
typingChange
Section titled “typingChange”Fired when the typing/“thinking” indicator should toggle.
conversationCreated
Section titled “conversationCreated”Fired when the controller lazily creates a conversation on first send.
Two things this table does not cover
Section titled “Two things this table does not cover”A custom bubble is a render hook, not a slot: React takes a renderBubble function,
the other three take a bubble slot that receives the message. It is per-message rather
than per-region, which is why it is shaped differently — see
Custom bubbles.
Placement inside a slot is yours. Nothing here is positional: put your controls in the
order you want them and push one to the end with margin-inline-start: auto — a logical
property, so it follows the reading direction. The worked example is in
The composer toolbar.