Error
A pre-built error page: status code, headline, detail message, and a configurable clear button.
Drop it into +error.svelte or the failed snippet of a svelte:boundary.
It fills the viewport below the header via the shared --ui-header-height variable.
Basic Usage
Pass an error object.
When message equals statusMessage it is hidden
automatically, so passing a raw SvelteKit error object never prints the same text twice.
Demos on this page constrain the height with class="min-h-0 py-12".
<script lang="ts">
import { Error } from 'sv5ui';
</script>
<Error
error={{
statusCode: 404,
statusMessage: 'Page not found',
message: 'The page you are looking for does not exist.'
}}
/>As the App Error Page
The intended home is src/routes/+error.svelte,
feeding SvelteKit's page.status and page.error straight in.
These docs use exactly this pattern in their own +error.svelte:
visit /docs/does-not-exist to see it live.
<!-- src/routes/+error.svelte -->
<script lang="ts">
import { page } from '$app/state';
import { Error } from 'sv5ui';
</script>
<Error
error={{
statusCode: page.status,
statusMessage: page.error?.message
}}
/>With Icon
icon renders above the status code.
<Error
icon="lucide:wifi-off"
error={{
statusCode: 503,
statusMessage: 'Service unavailable',
message: 'We are doing some maintenance. Please check back soon.'
}}
/>The Clear Button
By default a "Go back home" link navigates to redirect (default '/').
Pass ButtonProps to restyle it, or false to remove it.
<!-- Default: a "Go back home" link to `redirect` (default '/') -->
<Error error={{ statusCode: 404, statusMessage: 'Not found' }} />
<!-- Customize the button with ButtonProps -->
<Error
error={{ statusCode: 404, statusMessage: 'Not found' }}
redirect="/docs"
clear={{ label: 'Back to docs', color: 'secondary', variant: 'outline' }}
/>
<!-- Or hide it -->
<Error error={{ statusCode: 404, statusMessage: 'Not found' }} clear={false} />Resetting a svelte:boundary
With onClear the clear button becomes a
real <button>. Pass the boundary's reset function to recover in place.
Try it: crash the widget below, then reset it.
The widget is healthy.
<!-- With onClear the button becomes a real <button>:
perfect as the failed snippet of a svelte:boundary. -->
<svelte:boundary>
<Dashboard />
{#snippet failed(error, reset)}
<Error
as="div"
error={{
statusMessage: 'Something went wrong',
message: error instanceof Error ? error.message : String(error)
}}
clear={{ label: 'Try again', leadingIcon: 'lucide:rotate-ccw' }}
onClear={reset}
/>
{/snippet}
</svelte:boundary>Custom Snippets
Every region can be replaced: leading, statusCode, statusMessage, message, and links.
Children render after the links area.
<Error error={{ statusCode: 500 }}>
{#snippet leading()}
<img src="/broken-robot.svg" alt="" class="h-32" />
{/snippet}
{#snippet statusMessage()}
<h1 class="text-5xl font-black">Well, this is awkward.</h1>
{/snippet}
{#snippet links()}
<Button label="Go home" href="/" />
<Button label="Status page" variant="outline" href="https://status.example.com" />
{/snippet}
<!-- children render after the links area -->
<p class="mt-6 text-sm">Error ID: 8f3a-11ec</p>
</Error>UI Slots
Use the `ui` prop to override classes on internal elements.
| Slot | Description |
|---|---|
root | Centered flex column filling the viewport below the header (`min-h-[calc(100svh-var(--ui-header-height,0px))]`) |
leading | Icon area above the status code |
leadingIcon | The icon element itself |
statusCode | Small status code line |
statusMessage | Large heading |
message | Detail paragraph |
links | Clear button / links row |
Snippets
| Snippet | Description |
|---|---|
leading | Replaces the default icon area |
statusCode | Replaces the default status code rendering |
statusMessage | Replaces the default status message rendering |
message | Replaces the default message rendering |
links | Replaces the default clear button area |
children | Additional content rendered after the links area |
Props
| Prop | Type | Default |
|---|---|---|
error | { statusCode?, statusMessage?, message? } | - |
icon | string | - |
redirect | string | '/' |
clear | boolean | ButtonProps | true |
onClear | () => void | - |
as | keyof HTMLElementTagNameMap | 'main' |
ref | HTMLElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |