@signalwire/status-widget
One dependency-free script reads the PagerDuty status feed and renders it two ways: a quiet dot and label for the site footer, or a full service dashboard. No framework, no build step, and nothing to keep running at request time.
01 / Footer indicator
Four states and one failure state. A single degraded service does not read as a full outage, and a failed fetch renders neutral rather than a false green.
| Upstream severity | Indicator | Copy |
|---|---|---|
| all good | green | All systems operational |
| minor | gold | Some systems degraded |
| major | red | Active incident |
| maintenance | blue | Scheduled maintenance |
| fetch failed | grey | System status unreachable |
02 / Full dashboard
The widget ships semantic markup and stable class names. Colour, type and spacing come from custom properties, so a host page restyles it without forking anything.
03 / Install
Published to npm and mirrored on the SignalWire CDN, the same path the call widget uses.
<!-- CDN, no build step -->
<link rel="stylesheet"
href="https://cdn.signalwire.com/@signalwire/
status-widget/dist/swstatus.css">
<script src="https://cdn.signalwire.com/
@signalwire/status-widget/dist/swstatus.js"></script>
<sw-status
variant="footer"
src="https://cdn.signalwire.com/signalwire/status-widget/main/data/snapshot.json"
refresh="60"></sw-status>
// npm, for the Framer code component
// npm i @signalwire/status-widget
import SWStatus from '@signalwire/status-widget';
import '@signalwire/status-widget/swstatus.css';
SWStatus.mount(ref.current, {
variant: 'footer',
source: 'https://cdn.signalwire.com/signalwire/status-widget/main/data/snapshot.json',
refresh: 60000
});
// headless, if you want to render it yourself
const state = SWStatus.derive(await SWStatus.load(url));
// { overall, headline, services[], active[], upcoming[], history[] }
04 / How the data arrives
The status page API is public and needs no credentials. The only real obstacle is CORS, and that is solved by mirroring rather than by building a service.
The four endpoints below answer unauthenticated requests. No API token is involved, so there is no credential to keep out of client-side code.
What they do not send is Access-Control-Allow-Origin. A preflight returns
only Allow: GET,HEAD. That means a browser on signalwire.com cannot read
them directly, no matter how the fetch is written.
A scheduled job pulls the four endpoints and writes one merged
snapshot.json. That file goes to static hosting that already sends
Access-Control-Allow-Origin: *.
cdn.signalwire.com already does, on every response. So does
raw.githubusercontent.com, which the bundled GitHub Action targets with no secrets.
| /api/data | Page config, descriptions |
| /api/services | Service list |
| /api/post_enums | Status vocabulary |
| /api/posts | Incidents, maintenance |
impacts. The widget applies
the worst active impact per service, then rolls those up to an overall state, matching the
rule the PagerDuty dashboard itself uses.