Error pages
Not found, no access and something went wrong.
Built with
Error 404
We can't find that page
The link to “Q3 performance reviews” may be old, or the page was moved. Check the address or go back to your dashboard.
error-pages.tsx
"use client";
import { useState } from "react";
import {
LuArrowLeft,
LuCompass,
LuLifeBuoy,
LuRefreshCw,
LuServerCrash,
LuShieldAlert,
} from "react-icons/lu";
import { Button, EmptyState, Segment, SegmentedControl } from "@nexera-ui/react";
type ErrorKind = "404" | "403" | "500";
const ERRORS = {
"404": {
icon: <LuCompass />,
code: "Error 404",
title: "We can't find that page",
description:
"The link to “Q3 performance reviews” may be old, or the page was moved. Check the address or go back to your dashboard.",
primary: (
<Button size="md" leadingIcon={<LuArrowLeft />}>
Back to dashboard
</Button>
),
secondary: (
<Button size="md" variant="secondary">
Search Northwind
</Button>
),
},
"403": {
icon: <LuShieldAlert />,
code: "Error 403",
title: "You don't have access to Payroll",
description:
"Only People Ops admins can open payroll runs. Ask Sara Malik, your workspace admin, to give you access.",
primary: <Button size="md">Request access</Button>,
secondary: (
<Button size="md" variant="secondary" leadingIcon={<LuArrowLeft />}>
Go back
</Button>
),
},
"500": {
icon: <LuServerCrash />,
code: "Error 500",
title: "Something went wrong on our side",
description:
"Your changes are safe. Try again in a moment; if it keeps happening, contact support and quote reference NW-7F2K-91.",
primary: (
<Button size="md" leadingIcon={<LuRefreshCw />}>
Try again
</Button>
),
secondary: (
<Button size="md" variant="secondary" leadingIcon={<LuLifeBuoy />}>
Contact support
</Button>
),
},
} as const;
/** Error pages: not found, no access and something went wrong, each with a way forward. */
export default function ErrorPages() {
const [kind, setKind] = useState<ErrorKind>("404");
const error = ERRORS[kind];
return (
<div className="@container grid min-h-[560px] content-start gap-6 bg-page px-4 py-8 @3xl:px-8">
<SegmentedControl
aria-label="Error page"
selectedKeys={[kind]}
onSelectionChange={(keys) => {
setKind(([...keys][0] as ErrorKind | undefined) ?? kind);
}}
className="justify-self-center"
>
<Segment id="404" label="Not found" />
<Segment id="403" label="No access" />
<Segment id="500" label="Server error" />
</SegmentedControl>
<section
aria-labelledby="error-page-code"
className="grid place-items-center gap-2 rounded-xl border border-default bg-surface px-4 py-12"
>
<p id="error-page-code" className="text-body-small text-muted">
{error.code}
</p>
<EmptyState
size="lg"
headingLevel={2}
icon={error.icon}
title={error.title}
description={error.description}
primaryAction={error.primary}
secondaryAction={error.secondary}
/>
</section>
</div>
);
}
More states and system messages blocks
- Empty statesFirst use, no results and all done.
- Loading skeletonsPage and panel placeholders while data loads.
- Success confirmationA modal that confirms a finished task.
- ToastsShort confirmations with undo.
- Confirm a destructive actionName what will be deleted before deleting it.
- Maintenance and offlineTell people about downtime or lost connection.
- Long-running jobProgress for exports, imports and uploads.