Skip to main content

App Pages and DOM Structure

This page maps the app routes and important DOM areas. It is useful for plugin authors, testers, and contributors who need stable mental models of where UI mounts.

Angular Routes

RouteComponentPurpose
/RedirectRedirects to /dashboard.
/loginLoginComponentUser login.
/registerRegisterComponentUser registration.
/invite/:inviteIdInviteComponentResolve and accept invite links.
/dashboardDashboardComponentLanding dashboard after sign-in.
/peopleFindPeopleComponentDiscover and start direct messages with people.
/serversFindServersComponentSearch, discover, and join servers.
/create-serverCreateServerComponentCreate a new server.
/room/:roomIdChatRoomComponentMain server page with text, voice, members, and plugin panels.
/dmDmWorkspaceComponentDirect-message workspace.
/dm/:conversationIdDmWorkspaceComponentA selected direct-message conversation.
/pmDmWorkspaceComponentPrivate-message workspace (alias of the DM workspace).
/pm/:conversationIdDmWorkspaceComponentA selected private-message conversation.
/call/:callIdPrivateCallComponentActive private (1:1) call.
/settingsSettingsComponentApp, voice, server, plugin, desktop, theme, local API settings.
/plugin-storePluginStoreComponentBrowse plugin sources and install/update plugins.
/plugins/:pluginId/:pageIdPluginPageHostComponentHost for plugin app pages registered with api.ui.registerAppPage().

Page Shell

The renderer is an Angular app. The common shell contains router outlet content plus persistent app surfaces such as the server rail, title bar integrations, settings modals, and floating voice controls.

High-level structure:

<app-root>
<router-outlet></router-outlet>
<!-- global dialogs, overlays, floating voice controls, and desktop integrations -->
</app-root>

Server Page DOM

The server page is the most important page for plugins.

<app-chat-room>
<app-servers-rail></app-servers-rail>
<app-rooms-side-panel>
<section>Text Channels</section>
<section>Voice Channels</section>
<section data-testid="plugin-room-side-panel">
<button>View plugins</button>
<app-plugin-render-host></app-plugin-render-host>
</section>
<section>Members</section>
</app-rooms-side-panel>
<main>
<app-voice-workspace></app-voice-workspace>
<app-chat-messages>
<app-message-list></app-message-list>
<app-typing-indicator></app-typing-indicator>
<app-message-composer></app-message-composer>
<app-klipy-gif-picker></app-klipy-gif-picker>
</app-chat-messages>
</main>
</app-chat-room>

Text Channel Area

Text channel UI is owned by the chat domain.

<app-chat-messages>
<app-message-list>
<app-message-item></app-message-item>
</app-message-list>
<app-message-overlays></app-message-overlays>
<app-typing-indicator></app-typing-indicator>
<app-message-composer></app-message-composer>
</app-chat-messages>

Plugin touchpoints:

  • api.ui.registerComposerAction() adds composer actions.
  • api.ui.registerEmbedRenderer() renders declared custom embed payloads.
  • api.ui.mountElement() can mount into a selector such as app-chat-messages when the plugin has ui.dom.

Voice Area

Voice UI is split between channel membership, controls, and media workspace.

<app-rooms-side-panel>
<section>Voice Channels</section>
</app-rooms-side-panel>
<app-voice-controls></app-voice-controls>
<app-floating-voice-controls></app-floating-voice-controls>
<app-voice-workspace>
<app-voice-workspace-stream-tile></app-voice-workspace-stream-tile>
</app-voice-workspace>

Plugin touchpoints:

  • api.media.playAudioClip() plays local audio.
  • api.media.addCustomAudioStream() contributes audio to voice handling.
  • api.media.addCustomVideoStream() contributes a video stream.
  • api.channels.addAudioChannel() creates a voice channel entry when the plugin has channel management rights.

Plugin Store and Manager DOM

<app-plugin-store>
<!-- source management, search, plugin cards, install/update/uninstall actions -->
</app-plugin-store>

<app-plugin-manager>
<!-- installed plugins, capability grants, activate/reload/unload, logs, docs -->
</app-plugin-manager>

Plugin pages registered through api.ui.registerAppPage() render at /plugins/:pluginId/:pageId:

<app-plugin-page-host>
<app-plugin-render-host></app-plugin-render-host>
</app-plugin-page-host>

Plugin Render Host

PluginRenderHostComponent accepts plugin render functions that return either an HTMLElement or a string. Returning an HTMLElement is preferred for interactive UI. Returned strings are rendered as simple text content.

Stable Selectors for Tests and Plugins

Prefer plugin APIs over DOM selectors. When direct DOM mounting is necessary, use stable app selectors and keep cleanup through the returned disposable.

Common targets:

SelectorArea
bodyGlobal overlays or modals.
app-chat-messagesMain text channel surface.
app-rooms-side-panelServer side panel.
[data-testid="plugin-room-side-panel"]Plugin side-panel area in the server sidebar, including the View plugins trigger for registerToolbarAction() tiles.

Avoid depending on Tailwind utility classes; they are layout details and may change.