Appearance
Channel Plugins
What it does
A channel plugin replaces the entire chat area in a channel. While active, the plugin covers the message list, message input, and sidebar. It has the full width and height of the chat viewport.
When to use this context
Use channel plugins for:
- Rich experiences that need the full screen: polls, event cards, game dashboards, tournament brackets
- Apps that replace the chat: leaderboards, task managers, collaborative whiteboards
- Data-heavy visualizations: charts, analytics, activity logs
Channel plugins are powerful but intrusive. If you're building a small widget, use sidebar plugins instead.
Minimal example
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://app.dissent.chat/sdk/v1/dissent-plugin-sdk.iife.js"></script>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, sans-serif;
background: var(--bg, #0a0a12);
color: rgba(255,255,255,0.85);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.card {
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 16px;
padding: 32px;
max-width: 480px;
width: 100%;
text-align: center;
}
h1 { font-size: 24px; font-weight: 800; margin-bottom: 8px; }
p { font-size: 14px; color: rgba(255,255,255,0.5); }
</style>
</head>
<body>
<div class="card">
<h1 id="title">Loading…</h1>
<p id="server"></p>
</div>
<script>
async function main() {
const ctx = await Dissent.init({
onFallback: () => console.warn('Running outside Dissent — no context available'),
});
// Apply theme colours from the host app
for (const [k, v] of Object.entries(ctx.theme)) {
document.documentElement.style.setProperty(k, v);
}
document.getElementById('title').textContent = ctx.config.title ?? 'Channel Plugin';
document.getElementById('server').textContent = ctx.server.name;
// Theme updates when the user switches themes
Dissent.on('theme:change', (theme) => {
for (const [k, v] of Object.entries(theme)) {
document.documentElement.style.setProperty(k, v);
}
});
}
main().catch(err => console.error(err));
</script>
</body>
</html>Channel messages are off limits
A plugin cannot read the channel's messages — neither history nor new messages as they arrive. There is no getMessages() and no message:new event; the channel:read permission that once allowed it was removed on 2026-08-15. To share live state between members looking at your plugin, publish realtime events to your own install and listen with Dissent.on() (requires realtime; see postMessage Protocol).
Posting as the bot
With bot:post declared and granted, you can post messages to the channel:
javascript
await Dissent.postMessage('The event has started!');Requires bot:post; the user is asked to grant it on the consent card.
Gotchas
- The consent card follows your permissions. Declare none and the plugin loads straight away; declare any and each user is asked first. The tier is only a label.
ctx.channelis always available.ctx.channel.idandctx.channel.nameare safe to use in channel context.- The channel's chat is hidden while your plugin is shown. If members still need to talk alongside it, a sidebar plugin may be the better fit.
- Admin config is optional.
ctx.configmay be empty. Always provide sensible defaults:ctx.config.title ?? 'Default Title'.