Skip to Content
PatternsFeedbackError Page

Error Page

A full-page error display for 404, 500, and other error states. Built using Box, Column, Row, Icon, Text, and Button components.

404
Page Not Found
The page you're looking for doesn't exist or has been moved.

Source

'use client'; import { AlertCircle, ArrowLeft, Home, RefreshCw } from 'lucide-react'; import { Box, Button, Column, Icon, Row, Text } from '@umami/react-zen'; export function ErrorPage({ statusCode, title, description, showHomeButton = true, showBackButton = true, showRetryButton = false, onRetry, onBack, onHome, ...props }) { const defaultMessages = { 400: { title: 'Bad Request', description: 'The server could not understand your request.' }, 401: { title: 'Unauthorized', description: 'You need to sign in to access this page.' }, 403: { title: 'Forbidden', description: "You don't have permission to access this page." }, 404: { title: 'Page Not Found', description: "The page you're looking for doesn't exist." }, 500: { title: 'Server Error', description: 'Something went wrong on our end.' }, 503: { title: 'Service Unavailable', description: "We're temporarily offline." }, }; const defaults = statusCode ? defaultMessages[statusCode] : undefined; const displayTitle = title || defaults?.title || 'Something went wrong'; const displayDescription = description || defaults?.description || 'An unexpected error occurred.'; return ( <Column alignItems="center" justifyContent="center" padding="8" gap="6" minHeight="50vh" {...props}> <Column alignItems="center" gap="4"> {statusCode && <Text size="6xl" weight="bold" color="muted">{statusCode}</Text>} {!statusCode && ( <Row width="16" height="16" borderRadius="full" backgroundColor="red-100" alignItems="center" justifyContent="center"> <Icon size="lg" color="red"><AlertCircle /></Icon> </Row> )} <Column alignItems="center" gap="2"> <Text size="xl" weight="semibold">{displayTitle}</Text> <Box maxWidth="24rem" textAlign="center"><Text color="muted">{displayDescription}</Text></Box> </Column> </Column> <Row gap="3"> {showBackButton && ( <Button variant="outline" onPress={onBack || (() => window.history.back())}> <Row gap="2" alignItems="center"> <Icon size="sm"><ArrowLeft /></Icon> <Text>Go back</Text> </Row> </Button> )} {showRetryButton && ( <Button variant="outline" onPress={onRetry}> <Row gap="2" alignItems="center"> <Icon size="sm"><RefreshCw /></Icon> <Text>Try again</Text> </Row> </Button> )} {showHomeButton && ( <Button variant="primary" onPress={onHome || (() => (window.location.href = '/'))}> <Row gap="2" alignItems="center"> <Icon size="sm"><Home /></Icon> <Text>Go home</Text> </Row> </Button> )} </Row> </Column> ); } export function Error404(props) { return <ErrorPage statusCode={404} {...props} />; } export function Error500(props) { return <ErrorPage statusCode={500} showRetryButton {...props} />; }

Variations

500 Server Error

500
Server Error
Something went wrong on our end. Please try again later.

Custom error with retry

Connection Lost
We couldn't connect to the server. Please check your internet connection and try again.

403 Forbidden

403
Forbidden
You don't have permission to access this page.

Minimal (no status code)

Something went wrong
An unexpected error occurred. Please try again later.