Widget

@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.

Theme: purple · Section: heroopen in new tab ↗
npm install @wigtoken-temp/widget

Provider

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>
PropTypeDefaultNotes
serverstringrequiredBase URL of your wigtoken server
tokenstringrequiredEmbed-scope bearer token
pollbooleanfalseWhen true, polls instead of opening SSE
pollIntervalMsnumber2000Polling interval (fallback or forced)

Counters

Animated count-up. Updates on every SSE event from the server.

Live preview · streams from the demo serveropen ↗
<TokenCounter />
<TokenCounter mode="weighted" />
<CostCounter />
<MessageCounter />
ComponentProps
<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.

Live preview · streams from the demo serveropen ↗
<BurnSparkline range="1h" />
<BurnSparkline range="24h" />
<BurnSparkline range="7d" />
PropTypeDefault
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.

Live preview · streams from the demo serveropen ↗
<TopUsers limit={5} />
<TopModels limit={5} />
<TopMachines limit={5} />
ComponentProps
<TopUsers />limit?: number, by?: "cost" | "weighted" | "messages"
<TopModels />limit?, by?
<TopMachines />limit?, by?

Activity

Live preview · streams from the demo serveropen ↗
<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

Live preview · streams from the demo serveropen ↗
<EmbedPulseDot size={6} />
<EmbedPulseDot size={10} />
<EmbedPulseDot size={14} withLabel />
<ModelLegend />
ComponentProps
<EmbedPulseDot />size?: number (pixels), withLabel?: boolean, connectedColor?: string
<ModelLegend />

Layout primitives

Live preview · streams from the demo serveropen ↗
<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>
ComponentProps
<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.

Live preview · streams from the demo serveropen ↗
<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