Error pages
Usage
Use these full pages when a whole screen can't be shown. For a failure inside one part of a screen (a tile that didn't load, a save that failed) use an inline alert or the result panel in place, and keep the rest of the screen working.
- Keep the header. Error pages use the top-nav-only app shell, so people can navigate away without the back button.
- Plain language, no blame: say what happened, what is safe, and what to do next. No status codes as the headline, no jokes, no "Oops".
- 404: a search box plus the way home. 403: who you're signed in as, who can grant access, "Request access" and "Switch account". 500: "Try again", the status page, and a copyable reference ID. Offline: what is saved locally and that it will sync on its own.
- Correct HTTP status and a matching
<title>("Page not found — Fleetline"); the result title is the page's onlyh1. - Planned downtime is not a 500: use the service-unavailable pattern with the return time.
Anatomy
- Header —
header.top-navinside.app-shell--top-nav-only - Main —
main#main.app-shell__main.error-page(centres the panel vertically) - Result panel —
.result.result--page+ tone (--error,--warning,--no-permission) - Title —
h1.result__title; description; reference ID.result__reference(500) - Search (404) —
search.search.error-page__search - Actions —
.result__actions; technical detailsdetails.result__details(500, optional)
Examples
Each page renders in a frame; in the product the panel title is the h1 and the region is the document's <main>.
Error pages (404/500)
variant:404 — <title>Page not found — Fleetline</title>
We can’t find that page
The work order may have been archived, or the link has a typo. Search for it by number or plate.
Not found: plain words, no blame, a search box and the way home. Respond with HTTP 404.
variant:403 — <title>No access — Fleetline</title>
No access: say who you're signed in as, who can grant access, and offer to switch account. HTTP 403.
variant:500 — <title>Something went wrong — Fleetline</title>
Something went wrong on our side
We couldn’t load the dispatch board. Nothing you saved is lost. Try again in a minute; if it keeps happening, give support this reference: ERR-20261008-4QX7
Technical details
- Reference
- ERR-20261008-4QX7
- Time
- Request
- GET /dispatch/north-yard → 500
Server error: reassure about data, offer retry and the status page, and show a copyable reference ID. HTTP 500.
variant:offline — <title>You're offline — Fleetline</title>
You’re offline
This tablet can’t reach Fleetline. 2 service logs are saved on it and will send on their own when the connection is back.
Offline (service worker fallback on tablets): say what is safe locally and that it will sync without action.
<title>Something went wrong — Fleetline</title>
…
<div class="app-shell app-shell--top-nav-only">
<header class="top-nav app-shell__header">…</header>
<div class="app-shell__body">
<main class="app-shell__main error-page" id="main" tabindex="-1">
<section class="result result--page result--error" aria-labelledby="err-t">
<span class="result__icon" aria-hidden="true"><svg>…</svg></span>
<h1 class="result__title" id="err-t">Something went wrong on our side</h1>
<p class="result__description">… reference: <code class="result__reference">ERR-20261008-4QX7</code></p>
<div class="result__actions">
<a class="btn btn--primary" href="">Try again</a>
<a class="btn btn--ghost" href="https://status.fleetline.app">Check service status</a>
</div>
</section>
</main>
</div>
</div>
API
| Hook | Values | Purpose |
|---|---|---|
.error-page | block, on .app-shell__main | Centres the result panel in the available height |
.error-page__search | part, on search.search | Full-width search inside the centred panel (404) |
.result--page + tone | component modifiers | 404 info (default) · 403 --no-permission · 500 --error · offline --warning |
Do and don't
details.Accessibility
| Situation | Behavior |
|---|---|
| Full page load (server error page) | The <title> is announced; the h1 is the first heading in main |
| Client-side route fails | Update document.title, then move focus to the h1 (tabindex="-1") so the change is announced |
| Connection drops | Show the offline page (or an inline banner) and announce it once through role="status"; don't trap focus |
| Reference ID | Plain text, selectable with one click (user-select: all), readable by screen readers character by character |
Tone comes from the icon and the title words, never color alone. "Try again" for a page load is a link to the same URL (works without JavaScript); offline retry is a button because it only re-checks the connection.
Tokens
| Custom property | Purpose |
|---|---|
--size-container-sm | Max width of the 404 search |
--color-feedback-danger-*, --color-feedback-warning-*, --color-bg-muted | Icon disc tones via the result panel |
--space-16 | Page-level padding of .result--page |