@wigtoken-temp/widget
Drop-in React components for embedding wigtoken data on any site. ESM + CJS, ~28 KB minified, peer-deps on React 18+.
🎨 Live gallery: every component below is rendered live from the demo site — try it interactively, then come back here for the prop reference.
Playground
Swap components and themes inline. Powered by the same @wigtoken-temp/widget package you’d install — driven by a small mock backend so you don’t need a real wigtoken server to try it.
npm install @wigtoken-temp/widgetProvider
Every widget must be wrapped in a ProviderConfig so it knows which server to query and which token to authenticate with.
import { ProviderConfig } from "@wigtoken-temp/widget";
<ProviderConfig
server="https://token.example.com"
token="we_…" // embed-scope token, public-safe
poll={false} // SSE on by default; true → fallback poll
pollIntervalMs={2000} // used when poll=true OR SSE drops
>
{/* widgets go here */}
</ProviderConfig>| Prop | Type | Default | Notes |
|---|---|---|---|
server | string | required | Base URL of your wigtoken server |
token | string | required | Embed-scope bearer token |
poll | boolean | false | When true, polls instead of opening SSE |
pollIntervalMs | number | 2000 | Polling interval (fallback or forced) |
Counters
Animated count-up. Updates on every SSE event from the server.
<TokenCounter />
<TokenCounter mode="weighted" />
<CostCounter />
<MessageCounter />| Component | Props |
|---|---|
<TokenCounter /> | mode?: "raw" | "weighted", format?: FormatMode, size?: Size, theme?: Theme |
<CostCounter /> | format?: FormatMode, currency?: string, size?, theme? |
<WeightedTokenCounter /> | format?, size?, theme? — shortcut for mode="weighted" |
<MessageCounter /> | format?, size?, theme? |
FormatMode = "compact" | "full", Size = "sm" | "md" | "lg", Theme = "purple" | "teal" | "amber" | "mono" | "auto".
Burn sparkline
Inline SVG line chart of recent burn — no chart library dependency.
<BurnSparkline range="1h" />
<BurnSparkline range="24h" />
<BurnSparkline range="7d" />| Prop | Type | Default |
|---|---|---|
range | "1h" | "24h" | "7d" | "30d" | "24h" |
metric | "tokensWeighted" | "tokensRaw" | "costUsd" | "messages" | "tokensWeighted" |
size, theme, width | — | — |
Leaderboards
Top-N grouped by user, model family, or machine.
<TopUsers limit={5} />
<TopModels limit={5} />
<TopMachines limit={5} />| Component | Props |
|---|---|
<TopUsers /> | limit?: number, by?: "cost" | "weighted" | "messages" |
<TopModels /> | limit?, by? |
<TopMachines /> | limit?, by? |
Activity
<RecentActivity limit={6} />
<LiveTicker />RecentActivity polls (or reads from SSE if the provider is in SSE mode). LiveTicker always uses SSE — new messages animate in as they arrive.
Status & legend
<EmbedPulseDot size={6} />
<EmbedPulseDot size={10} />
<EmbedPulseDot size={14} withLabel />
<ModelLegend />| Component | Props |
|---|---|
<EmbedPulseDot /> | size?: number (pixels), withLabel?: boolean, connectedColor?: string |
<ModelLegend /> | — |
Layout primitives
<StatGrid>
<MetricCard label="Today" value="12,418" sub="+8%" />
<MetricCard label="This week" value="68,201" sub="+22%" />
<MetricCard label="This month" value="284,910" sub="+11%" />
<MetricCard label="All time" value="1.2M" />
</StatGrid>| Component | Props |
|---|---|
<MetricCard /> | label, value, sub?, size?, theme? |
<StatGrid> | children — responsive 2-/4-col grid |
Hero composition
Everything together — what a real marketing page hero looks like.
<ProviderConfig server={env.SERVER} token={env.TOKEN}>
<h1>
Our crew has processed <WeightedTokenCounter /> input-equivalent tokens.
</h1>
<StatGrid>
<MetricCard label="Tokens (weighted)" value={<WeightedTokenCounter />} />
<MetricCard label="Cost" value={<CostCounter />} />
<MetricCard label="Messages" value={<MessageCounter />} />
<MetricCard label="Status" value={<EmbedPulseDot size={10} withLabel />} />
</StatGrid>
<BurnSparkline range="24h" />
</ProviderConfig>Theming
Set theme on individual components or override CSS custom properties:
:root {
--wt-accent: #b794f4;
--wt-accent-fg: #1a202c;
--wt-bg: #0a0a0a;
--wt-fg: #f5f5f5;
--wt-muted: #71717a;
}SSE & offline
The provider establishes one SSE connection to /embed/stream and fans out updates to every consumer. If SSE fails (proxy buffering, captive portal), it falls back to polling at pollIntervalMs. Reconnects with exponential backoff up to 60s.
SSR
Counters render 0 on the server and hydrate to real values once SSE is alive. No layout shift if you reserve space with CSS.
See also
- Live demo — the full showcase with theme switcher and editable config
- API reference — endpoints the widget hits behind the scenes
- Self-hosting — 2-layer security for embedding