Appearance
Sidebar Plugins
What it does
A sidebar plugin renders as a compact card in the right sidebar of a server. Multiple sidebar plugins stack vertically. The card is always visible (when the sidebar is open) alongside the channel's message area.
When to use this context
Use sidebar plugins for:
- Live stats: server activity, member count, online users
- Countdowns: event timers, deployment schedules
- Quick widgets: weather, time zone, leaderboards
- Glanceable information: no click-through required
Sidebar plugins should be lightweight and non-intrusive. Avoid long scrolling content.
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: transparent;
color: rgba(255,255,255,0.85);
padding: 12px;
}
.widget {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}
.label {
font-size: 12px;
color: rgba(255,255,255,0.5);
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: 600;
}
.value {
font-size: 20px;
font-weight: 800;
font-variant-numeric: tabular-nums;
}
</style>
</head>
<body>
<div class="widget">
<div>
<div class="label">Event starts in</div>
<div class="value" id="countdown">--:--:--</div>
</div>
</div>
<script>
function formatCountdown(ms) {
if (ms <= 0) return 'Live!';
const totalSeconds = Math.floor(ms / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}
async function main() {
const ctx = await Dissent.init({
onFallback: () => {
document.getElementById('countdown').textContent = 'Not in Dissent';
},
});
// Apply theme
for (const [k, v] of Object.entries(ctx.theme)) {
document.documentElement.style.setProperty(k, v);
}
// Parse event time from config
const eventTime = ctx.config.eventTime ? new Date(ctx.config.eventTime).getTime() : Date.now() + 3600000;
// Update countdown every second
setInterval(() => {
const now = Date.now();
const ms = eventTime - now;
document.getElementById('countdown').textContent = formatCountdown(ms);
}, 1000);
// Sync theme on change
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>Gotchas
- Keep height compact. Sidebar cards don't scroll. Stay under 200px in height for best UX.
- Multiple plugins stack vertically. Don't assume you're the only sidebar plugin. Keep your card self-contained.
background: transparentlooks better than solid background. Let the app's theme show through.ctx.channelmay be undefined. In sidebar context, the user might not have a channel selected. Always guard:if (ctx.channel?.id) { /* ... */ }.