Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Error page patterns for 404, 500, and maintenance states. Guide users with clear messaging and helpful actions.
Error pages appear when something goes wrong or content is unavailable. They should clearly communicate the issue, reassure users, and provide actionable next steps to get them back on track.
Key features:
data-layout="cover"A 404 page appears when users navigate to a URL that doesn't exist. Display a prominent error code, explain the issue, and provide navigation options.
<body data-layout="cover" data-layout-min="100vh" data-layout-padding="l"> <main data-layout="center" data-layout-max="narrow" data-layout-principal class="error-content" data-layout-gap="xl"> <span class="error-code">404</span> <hgroup class="spaced"> <h1>Page not found</h1> <p>Sorry, we couldn't find the page you're looking for. It may have been moved or deleted.</p> </hgroup> <footer data-layout="stack" data-layout-gap="m"> <a href="/" class="button"> <icon-wc name="home"></icon-wc> Go back home </a> <nav data-layout="cluster" data-layout-gap="m" data-layout-justify="center" class="error-links" aria-label="Additional navigation"> <a href="/search">Search</a> <a href="/sitemap">Sitemap</a> <a href="/contact">Contact support</a> </nav> </footer> </main></body>
A 500 page appears during server-side errors. Use a warning icon, acknowledge the problem, and offer options to retry or navigate elsewhere.
<body data-layout="cover" data-layout-min="100vh" data-layout-padding="l"> <main data-layout="center" data-layout-max="narrow" data-layout-principal class="error-content" data-layout-gap="xl"> <header data-layout="stack" data-layout-gap="m" data-layout-align="center"> <icon-wc name="alert-triangle" class="error-icon"></icon-wc> <span class="error-code">Error 500</span> </header> <hgroup class="spaced"> <h1>Something went wrong</h1> <p>We're experiencing technical difficulties. Our team has been notified and is working on a fix. Please try again later.</p> </hgroup> <div data-layout="cluster" data-layout-gap="m" data-layout-justify="center"> <button data-action="reload"> <icon-wc name="refresh-cw"></icon-wc> Try again </button> <a href="/" class="button secondary"> <icon-wc name="home"></icon-wc> Go back home </a> </div> <nav data-layout="cluster" data-layout-gap="m" data-layout-justify="center" class="error-links" aria-label="Additional navigation"> <a href="/status">Check system status</a> <a href="/contact">Contact support</a> </nav> </main> <script> document.querySelector('[data-action="reload"]') .addEventListener('click', () => location.reload()); </script></body>
A maintenance page displays during scheduled downtime. Communicate the situation, provide an estimated return time, and offer ways to stay updated.
<body data-layout="cover" data-layout-min="100vh" data-layout-padding="l"> <main data-layout="center" data-layout-max="narrow" data-layout-principal class="maintenance-content" data-layout-gap="xl"> <icon-wc name="wrench" class="maintenance-icon"></icon-wc> <hgroup class="spaced"> <h1>Under maintenance</h1> <p>We're currently performing scheduled maintenance to improve our services. We'll be back shortly.</p> </hgroup> <span class="eta-badge"> <icon-wc name="clock"></icon-wc> Estimated return: <time datetime="14:00-05:00">2:00 PM EST</time> </span> <section data-layout="stack" data-layout-gap="s"> <p class="section-label">Get notified when we're back online:</p> <form class="notify-form" action="/notify" method="POST"> <input type="email" name="email" placeholder="Enter your email" required aria-label="Email address"/> <button type="submit">Notify me</button> </form> </section> <section data-layout="stack" data-layout-gap="m"> <p class="section-label">Follow us for updates:</p> <nav class="social-links" aria-label="Social media"> <ul> <li><a href="https://twitter.com" aria-label="Twitter"> <icon-wc name="twitter"></icon-wc> </a></li> <li><a href="https://facebook.com" aria-label="Facebook"> <icon-wc name="facebook"></icon-wc> </a></li> <li><a href="/status" aria-label="Status page"> <icon-wc name="activity"></icon-wc> </a></li> </ul> </nav> </section> </main></body>
Error pages are built from layout primitives. Here are the key components:
| Element | Purpose | Customization |
|---|---|---|
data-layout="cover" |
Full-page vertical centering | Set minimum height with data-layout-min |
data-layout="center" |
Horizontally centers content | Control width with data-layout-max |
data-layout="stack" |
Vertical spacing between elements | Adjust gap with data-layout-gap |
<icon-wc> |
Visual indicator of error type | Size via --icon-size, color via CSS |
data-layout="cluster" |
Horizontal grouping of actions | Alignment with data-layout-justify |
<main> landmark: Each error page wraps content in a <main> element, giving screen readers a clear landmark for the primary content.<h1>: Each page uses exactly one <h1> describing the error, maintaining proper heading hierarchy.<icon-wc> elements render with aria-hidden="true" by default, keeping them out of the accessibility tree.<nav aria-label="Additional navigation"> so screen readers can identify them as a navigation region.Choose icons that clearly indicate the error type. Common icons from the Lucide set:
| Icon | Name | Use For |
|---|---|---|
alert-triangle |
Server errors, warnings | |
file-x |
File not found, 404 errors | |
wrench |
Maintenance mode | |
wifi-off |
Connection issues | |
lock |
Access denied, 403 errors | |
clock |
Timeout errors | |
server-crash |
Server down | |
shield-alert |
Security errors |
When there's no content to display
Loading placeholders for content
Center content horizontally