--- status: complete created: '2026-03-16' tags: - embed - widget priority: low created_at: '2026-03-16T07:51:51.430Z' depends_on: - 009-public-sharing updated_at: '2026-03-16T10:01:28.760Z' completed_at: '2026-03-16T10:01:28.760Z' completed: '2026-03-16' transitions: - status: complete at: '2026-03-16T10:01:28.760Z' --- # Embeddable Poll Widget > **Status**: ✅ Complete · **Priority**: Low · **Created**: 2026-03-16 · **Tags**: embed, widget ## Overview Allow polls to be embedded on external websites and potentially in messaging apps. This extends the public sharing with an inline experience. ## Design ### Embed Options 1. **iframe embed** (simplest, broadest support) - `` - Renders a compact read-only results view - Self-contained, works anywhere iframes are supported - Uses `postMessage` to communicate height for responsive sizing 2. **oEmbed protocol** (for platforms that support it—Notion, WordPress, Medium, etc.) - Endpoint: `https://evocracy.app/oembed?url=https://evocracy.app/poll/[pollId]` - Returns iframe-based rich embed 3. **Web Component** (deferred to v2) - `` - `` - Shadow DOM for style isolation - Deferred: iframe covers 90% of use cases ### Messenger Compatibility - iMessage / WhatsApp / Telegram: Open Graph link previews (handled by spec 009) - Slack / Discord: oEmbed + Open Graph unfurling - Actual inline voting in messengers is not feasible without platform-specific bots ### Embed Route - `/embed/[id]` — minimal chrome, compact layout, no navigation - Auto-resizes via `postMessage` to parent frame ## Plan - [ ] Create `/embed/[id]` route with compact poll results view - [ ] Implement iframe auto-resize via postMessage - [ ] Add "Get embed code" UI to poll management page - [ ] Implement oEmbed endpoint (`/oembed`) - [ ] ~Build web component wrapper (`widget.js`)~ (deferred to v2) ## Test - [ ] iframe embed renders correctly on a test HTML page - [ ] Auto-resize adjusts to content height - [ ] oEmbed endpoint returns valid JSON - [ ] Web component renders in isolation (Shadow DOM) ## Notes - **DECIDED**: Web component deferred to v2—iframe alone covers 90% of use cases - Messenger "embeds" are really just link previews, not interactive widgets