StatusPage component
The data-only page component, its props and what the shell owns.
<StatusPage /> renders a complete status page from one snapshot. It owns
everything that is not visual — colour mode, brand tokens, monitor grouping
and the lazily mounted subscribe dialog — and hands the result to the
configured theme, which is the only thing that decides how the page looks.
Passing configuration-derived values keeps one decision in one place: change
theme or branding in heyo-status.config.ts and the page follows.
Props
The payload from statusPage.api.getSnapshot() or GET /status.
Defaults to "Heyo Status". Used for accessible labelling, not as visible
header text.
{ logo?, name? }. Controls the header mark and its optional label.
Defaults to "slate". Selects the layout and publishes data-theme.
Defaults to "system". The initial colour-mode preference.
Published as CSS custom properties on the page container.
showLatency, showLatencyChart, showUptimePercent, uptimePeriods.
Defaults to "/api/heyo-status". Feed and subscription URLs are derived
from it.
Defaults to `${basePath}/rss.xml`.
Defaults to false. Shows the subscribe control.
Which tabs the built-in dialog offers.
Link to your own subscribe page instead of opening the dialog.
Overrides the base-path-derived POST target of the dialog.
Take over the button entirely.
Defaults to true.
Added to the page container.
Server rendering
The component is "use client", but it renders fully on the server. All the
page's primary content — overall status, monitor cards, uptime grids,
incident timelines, maintenance windows — is static markup. Incident
disclosures and monitor groups are native <details> elements, so they still
open when the bundle fails to load, which is exactly when people come looking
for a status page.
Only two things need JavaScript: the colour-mode toggle and the subscribe
dialog. The dialog is lazy()-imported on first use, because its modal, tabs
and form are more component code than the rest of the page put together.
Every framework template awaits statusPage.api.getSnapshot() in a loader,
a server component or Astro frontmatter. Fetching it from the browser would
make the first paint an empty page and send the database read on the
critical path.
Framework placement
Astro needs client:load: without it the toggle and the dialog render as
inert markup.
Rendering a remote snapshot
The snapshot is plain JSON, so a page can live in a different application from the monitoring runtime:
Dates arrive as ISO strings over HTTP. Revive them before rendering, or use
the primitives that accept Date | string directly.