<scriptlang="ts">import { Error as ErrorPage } from'$lib/components/ui/error';</script><ErrorPagestatus={404}error={{ message: 'The page you requested may have moved, changed its name, or never existed.' }}class="min-h-[32rem]"/>
More examples
Additional error details
Render support references, disclosure panels, or any custom content beneath the error.
504
Error 504
The server took too long to respond
Your request is safe, but the service took too long to answer.
The upstream service did not respond before timeout.
error-custom-content.demo.svelte
<scriptlang="ts">import { Error as ErrorPage } from'$lib/components/ui/error';</script>{#snippetchildren()} <divclass="mx-auto max-w-md text-sm text-muted-foreground"> <p>Reference: req_7f8a21</p> <detailsclass="mt-3 rounded-lg border border-border bg-background p-3 text-left"> <summaryclass="cursor-pointer font-medium text-foreground">Technical details</summary> <pclass="mt-2 font-mono text-xs">The upstream service did not respond before timeout.</p> </details> </div>{/snippet}<ErrorPagestatus={504}error={{ message: 'Your request is safe, but the service took too long to answer.' }}{children}class="min-h-[32rem]"/>
Message only
Hide the default recovery actions for errors that should not offer navigation or retry.
403
Error 403
You cannot access this page
Ask a workspace administrator if you believe you should have access.
error-minimal.demo.svelte
<scriptlang="ts">import { Error as ErrorPage } from'$lib/components/ui/error';</script><ErrorPagestatus={403}error={{ message: 'Ask a workspace administrator if you believe you should have access.' }}homeHref={null}showRetry={false}class="min-h-[32rem]"/>
Installation
Install directly from the hosted registry with the shadcn-svelte CLI.
In +error.svelte, import page from $app/state and pass status={page.status} and error={page.error}. Error derives a friendly title from common HTTP statuses and displays the error message SvelteKit exposes. Use title or message to override either value, configure the home and retry actions, and pass children for support references, technical details, or custom controls below the error.
API reference
Prop
Type
Default
Description
status
number
required
HTTP status code used to select the error presentation.
error
App.Error | Error | string | null
required
SvelteKit error object whose message is displayed.
title
string
derived from status
Overrides the generated heading.
message
string
error.message
Overrides the displayed supporting message.
homeHref
string | null
/
Destination of the home recovery action.
homeLabel
string
Go home
Label displayed by the home recovery action.
showRetry
boolean
true
Shows the retry recovery action when enabled.
retryLabel
string
Try again
Label displayed by the retry action.
onRetry
() => void
location.reload
Called when the retry action is selected.
children
Snippet
—
Content rendered inside the component.
class
string
—
Tailwind CSS classes applied to the component root.
contentClass
string
—
Tailwind CSS classes applied to the content.
childrenClass
string
—
Tailwind CSS classes applied to the children.
Source
These files are included in the registry item and copied into the consuming project.
error.svelte
<scriptmodulelang="ts">importtype { Snippet } from'svelte';importtype { HTMLAttributes } from'svelte/elements';exporttypeErrorProps=Omit<HTMLAttributes<HTMLDivElement>, 'title'|'children'> & {status:number;error:App.Error|Error|string|null|undefined;title?:string;message?:string;homeHref?:string|null;homeLabel?:string;showRetry?:boolean;retryLabel?:string;onRetry?: () =>void;children?:Snippet;class?:string;contentClass?:string;childrenClass?:string; };exportfunctionerrorTitle(status:number) {consttitles:Record<number, string> = {400: 'That request did not look right',401: 'Sign in to continue',403: 'You cannot access this page',404: 'This page wandered off',408: 'The request took too long',409: 'Something changed along the way',422: 'We could not process that',429: 'A little too much, too quickly',500: 'Something went wrong on our side',502: 'The server returned a bad response',503: 'We will be right back',504: 'The server took too long to respond' };return titles[status] ?? (status >=500?'Something went wrong':'We hit a problem'); }</script><scriptlang="ts">import ArrowLeftIcon from'@lucide/svelte/icons/arrow-left';import RefreshCwIcon from'@lucide/svelte/icons/refresh-cw';import TriangleAlertIcon from'@lucide/svelte/icons/triangle-alert';import { Button } from'$lib/components/ui/button';import { cn } from'$lib/utils.js';let { status, error, title, message, homeHref ='/', homeLabel ='Go home', showRetry =true, retryLabel ='Try again', onRetry, children,class: className, contentClass, childrenClass,...restProps }:ErrorProps= $props();constcomponentId= $props.id();consttitleId=`${componentId}-title`;constmessageId=`${componentId}-message`;constresolvedTitle= $derived(title ??errorTitle(status));consterrorMessage= $derived( message ?? (typeof error ==='string'? error: (error?.message ??'An unexpected error prevented this page from loading.')) );functionretry() {if (onRetry) {onRetry();return; } window.location.reload(); }</script><div{...restProps}data-slot="error"data-status={status}role="alert"aria-labelledby={titleId}aria-describedby={messageId}class={cn('relative isolate grid min-h-[70svh] w-full place-items-center overflow-hidden rounded-2xl bg-background px-6 py-16 text-center', className )}> <divclass="pointer-events-none absolute inset-x-0 top-0 -z-20 mx-auto h-80 max-w-3xl rounded-full bg-primary/8 blur-3xl" ></div> <divclass="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_center,transparent_0%,var(--color-background)_70%)]" ></div> <divaria-hidden="true"class="pointer-events-none absolute top-1/2 -z-10 -translate-y-1/2 bg-gradient-to-b from-foreground/8 to-transparent bg-clip-text text-[clamp(10rem,35vw,24rem)] leading-none font-black tracking-tighter text-transparent select-none" > {status} </div> <divclass={cn('flex w-full max-w-xl flex-col items-center', contentClass)}> <divclass="mb-6 grid size-14 place-items-center rounded-2xl border border-border bg-card text-foreground shadow-lg shadow-foreground/5" > <TriangleAlertIconclass="size-6"aria-hidden="true" /> </div> <pclass="rounded-full border border-border bg-background/80 px-3 py-1 font-mono text-xs font-medium tracking-wider text-muted-foreground uppercase shadow-xs backdrop-blur" > Error {status} </p> <h1id={titleId} class="mt-5 text-3xl font-bold tracking-tight text-balance sm:text-5xl"> {resolvedTitle} </h1> <pid={messageId} class="mt-4 max-w-lg text-base leading-7 text-pretty text-muted-foreground"> {errorMessage} </p> {#if homeHref || showRetry} <divclass="mt-8 flex flex-wrap items-center justify-center gap-3"> {#if homeHref} <Buttonhref={homeHref} size="lg"> <ArrowLeftIconaria-hidden="true" /> {homeLabel} </Button> {/if} {#if showRetry} <Buttonvariant="outline"size="lg"onclick={retry}> <RefreshCwIconaria-hidden="true" /> {retryLabel} </Button> {/if} </div> {/if} {#if children} <divclass={cn('mt-10 w-full border-t border-border pt-6', childrenClass)}> {@renderchildren()} </div> {/if} </div></div>