Skip to content
weftGitHub

SystemPage

The pages for not found, no access, server error, maintenance and nothing yet.

SourcePackage @weft-js/warp

Preview

tsx
import { SystemPage } from '@weft-js/warp'export function SystemPage404() {  return (    <SystemPage as="h3" kind="404" onSearch={() => {}} searchLabel="Search weft" primary={{ label: 'Go to dashboard' }} secondary={{ label: 'Report a broken link' }} meta="/projects/9921 · ref req_8f2a1c" />  )}

Installation

npm install @weft-js/warp

Usage

tsx
import { SystemPage } from '@weft-js/warp'<SystemPage as="h3" kind="404" onSearch={() => {}} searchLabel="Search weft" primary={{ label: 'Go to dashboard' }} secondary={{ label: 'Report a broken link' }} meta="/projects/9921 · ref req_8f2a1c" />

No access

Asking for access moves it to pending, with Withdraw.

tsx
import { state } from '@weft-js/core'import { SystemPage } from '@weft-js/warp'export function SystemPage403() {  const pending = state(false)  return <SystemPage as="h3" kind="403" autofocus={false} object={PROJECT} account="noor@weft.dev" accounts={ACCOUNTS} onSwitch={() => {}} request={{ approvers: 'Mara and Jun', pending: pending.value, onSend: () => (pending.value = true), onWithdraw: () => (pending.value = false) }} requestId="req_7Q2K-91XF" />}type Status = 'Live' | 'Building' | 'Failed' | 'Paused'const PROJECTS: { id: string; name: string; owner: string; region: string; status: Status; deploys: number; uptime: number; latency: number; cost: number; updated: string }[] = [  { id: 'storefront', name: 'storefront', owner: 'Priya Raman', region: 'eu-west', status: 'Live', deploys: 412, uptime: 99.98, latency: 84, cost: 1240, updated: '2026-10-31' },  { id: 'checkout', name: 'checkout', owner: 'Tomás Oliveira', region: 'eu-west', status: 'Live', deploys: 288, uptime: 99.95, latency: 112, cost: 980, updated: '2026-10-31' },  { id: 'search-api', name: 'search-api', owner: 'Lena Fischer', region: 'us-east', status: 'Building', deploys: 196, uptime: 99.91, latency: 146, cost: 1610, updated: '2026-10-30' },  { id: 'billing', name: 'billing', owner: 'Mara Lindqvist', region: 'us-east', status: 'Live', deploys: 154, uptime: 99.99, latency: 73, cost: 720, updated: '2026-10-29' },  { id: 'mobile-bff', name: 'mobile-bff', owner: 'Sam Okafor', region: 'ap-south', status: 'Failed', deploys: 233, uptime: 99.42, latency: 208, cost: 860, updated: '2026-10-29' },  { id: 'notifier', name: 'notifier', owner: 'Jun Tanaka', region: 'eu-north', status: 'Live', deploys: 97, uptime: 99.97, latency: 58, cost: 310, updated: '2026-10-27' },  { id: 'reports', name: 'reports', owner: 'Noor Haddad', region: 'us-west', status: 'Paused', deploys: 41, uptime: 99.8, latency: 321, cost: 190, updated: '2026-10-22' },  { id: 'edge-cache', name: 'edge-cache', owner: 'Jun Tanaka', region: 'global', status: 'Live', deploys: 318, uptime: 100, latency: 21, cost: 1430, updated: '2026-10-31' },  { id: 'auth', name: 'auth', owner: 'Mara Lindqvist', region: 'eu-west', status: 'Live', deploys: 176, uptime: 99.99, latency: 66, cost: 540, updated: '2026-10-28' },  { id: 'ingest', name: 'ingest', owner: 'Lena Fischer', region: 'us-east', status: 'Live', deploys: 264, uptime: 99.93, latency: 131, cost: 2120, updated: '2026-10-30' },]const ACCOUNTS = [{ id: 'mara', email: 'mara@weft.dev', detail: 'weft · this workspace', current: true }, { id: 'side', email: 'mara@sample.dev', detail: 'Sample Co · has access', hasAccess: true }]const PROJECT = { title: PROJECTS[3]!.name, owner: PROJECTS[3]!.owner }

Server error

Pair it with <Boundary>. The error's message is never shown.

tsx
import { state } from '@weft-js/core'import { SystemPage } from '@weft-js/warp'export function SystemPage500() {  const tries = state(0)  return <SystemPage as="h3" kind="500" onRetry={() => tries.value++} secondary={{ label: 'Status page' }} requestId={`req_1a9f-${tries.value}`} />}

Maintenance

Use kind set to maintenance with backAt to say when the service returns.

tsx
import { SystemPage } from '@weft-js/warp'export function Maintenance() {  return (    <SystemPage as="h3" kind="maintenance" backAt="14:00 UTC" secondary={{ label: 'Status page' }} />  )}

Nothing yet

Use kind set to empty with primary and secondary to offer a first step.

tsx
import { SystemPage } from '@weft-js/warp'export function Empty() {  return (    <SystemPage as="h3" kind="empty" title="No projects yet" description="Connect a repository and your first deploy runs in about a minute." primary={{ label: 'New project' }} secondary={{ label: 'Import' }} />  )}

Accessibility

  • This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and warp's parts keep their roles and labels.

API Reference

PropTypeDefaultDescription
kind"empty" | "404" | "403" | "500" | "maintenance"—Which page.
titleunknown—Replaces the heading.
descriptionunknown—Replaces the line under it.
codeunknown—The small line above the heading.
primary{ label: unknown; onClick?: (() => void) | undefined; href?: string | un…—The main action.
secondary{ label: unknown; onClick?: (() => void) | undefined; href?: string | un…—The quieter action.
searchLabelstring—The 404 search field's label. Default "Search".
errorunknown—The error, for the Boundary form; its message is never shown.
requestIdstring—The support line.
metaunknown—Extra support text: a path, an incident.
backAtunknown—Maintenance: "Back at 14:00 UTC", and the local-time line in description.
object{ title: string; owner?: string | undefined; }—403: what was asked for and by whom.
accountstring—403: the signed-in account, as in "You're signed in as ana@weft.dev".
requestAccessRequest—403: the access request: who approves it, whether it is pending, and what sending or withdrawing does.
accountsSwitchAccount[]—403: other signed-in accounts, offered in a Switch account menu.
grantedbooleanfalse403: access came through: children is the object, loaded in place.
as"h2" | "h3"—The heading level.
autofocusboolean—Focus the title on load, so the route change is heard (default: 403).
childrenunknown—What it contains.
EventTypeDefaultDescription
onSearch((q: string) => void)—404: the search field.
onRetry(() => void)—500: retry from <Boundary>.
onSwitch((id: string | undefined) => void)—Called with the account picked, or undefined to sign in as someone else.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="system-page"] [data-part="body"]

bodysearchactionsmeta

RelatedConn bannerRate limited