@polst-web/widget
v0.7.3
Published
Embeddable POLST widget (script/SDK mode). Zero runtime deps, Shadow DOM rendering.
Readme
@polst-web/widget
Embeddable POLST widget for script-tag / SDK embedding. Zero runtime dependencies, browser-only, style-isolated via Shadow DOM.
Install
npm install @polst-web/widgetOr load from a CDN (no install needed):
<script
type="module"
async
src="https://unpkg.com/@polst-web/widget/dist/widget.esm.js"
></script>
<!-- or jsdelivr -->
<script
type="module"
async
src="https://cdn.jsdelivr.net/npm/@polst-web/widget/dist/widget.esm.js"
></script>Pin to a specific version (@polst-web/[email protected] or @0.7.0) for production stability.
Quick start
Drop a marker element anywhere on your page; the widget hydrates it on DOMContentLoaded:
<!-- single polst -->
<div data-polst="abc123def456"></div>
<!-- campaign player -->
<div data-polst-campaign="cmp_456" data-auto-advance="true"></div>
<!-- brand feed -->
<div data-polst-brand="acme" data-mode="mixed"></div>
<script
type="module"
async
src="https://unpkg.com/@polst-web/widget/dist/widget.esm.js"
></script>Each hydrated container is style-isolated inside a Shadow DOM root — host-page CSS does not leak in, widget CSS does not leak out.
Self-mounting <script> (Disqus / Intercom pattern)
A single tag both loads the widget and renders an embed:
<!-- inline: creates a sibling div immediately before the script -->
<script
src="https://unpkg.com/@polst-web/widget/dist/widget.nomodule.js"
data-polst="abc123def456"
></script>
<!-- targeted: mounts into an existing element -->
<div id="polst-slot"></div>
<script
src="https://unpkg.com/@polst-web/widget/dist/widget.nomodule.js"
data-polst="abc123def456"
data-target="#polst-slot"
></script>Programmatic API
For build-tooled consumers (Vite / Webpack / Next.js / etc.):
import { mount, configureOrigins } from "@polst-web/widget";
// Optional: point at a non-prod env before mounting
configureOrigins({
apiOrigin: "https://staging-api.polst.app",
appOrigin: "https://staging.polst.app",
});
mount(document.querySelector("#my-target"), {
polst: "abc123def456",
theme: "dark",
});The full programmatic surface is exposed via window.Polst.* after the script loads (mount, configure, renderPolstCard, renderCampaignPlayer, renderBrandFeed, etc.).
Config attributes
| Attribute | Applies to | Type | Notes |
| -------------------------- | ------------------- | ------- | ----- |
| data-polst | polst marker | string | Polst short id |
| data-polst-campaign | campaign marker | string | Campaign id |
| data-polst-brand | brand marker | string | Brand slug |
| data-target | script-tag only | string | CSS selector; if absent, inserts a sibling div |
| data-theme | any | enum | "light", "dark", or "auto" |
| data-accent | any | string | 6-char hex color override (no #) |
| data-hide-title | any | boolean | Hide the widget title |
| data-hide-brand | any | boolean | Hide the "by <brand>" line |
| data-auto-advance | campaign | boolean | Auto-advance campaign steps after a vote |
| data-mode | brand | enum | "polsts", "campaigns", or "mixed" |
| data-on-vote | any | string | Name of a function on window to call on vote |
| data-on-complete | campaign | string | Name of a function on window to call on completion |
| data-polst-auto-observe | <html> or <body>| presence| Install a MutationObserver to hydrate late-added markers |
Boolean attributes accept "", "true", "1", "yes" (truthy) or "false", "0", "no" (falsy). Unknown callback names are logged with the [polst] prefix and silently dropped — they never throw into the host page.
SPA / dynamic content
For pages that insert markers after initial load, add data-polst-auto-observe to <html> or <body>:
<html data-polst-auto-observe>
…
</html>This installs a single MutationObserver that hydrates marker elements as they appear. Each hydrated container is stamped with data-polst-hydrated="1", so re-running the script is always a no-op.
Build outputs
dist/widget.esm.js+ map — ES2020 module for modern browsers (~19 KB gzipped)dist/widget.nomodule.js+ map — ES5 IIFE bundle fornomoduletags (~20 KB gzipped)dist/widget.d.ts— TypeScript declarationsdist/integrity.json— SRI hashes for the JS artifacts
