Result
Centered exception and outcome block for 403/404/500/success/error/info with default status icons and inline recovery actions.
Result is a centered status block for post-action outcomes and exception pages — success, error, info, and HTTP-style 403 / 404 / 500. Hosts supply the title, optional subtitle, and recovery actions in extra. Use size="page" (default) inside PageContainer with surface="plain"; use size="region" for compact in-panel load failures. Successful no-content belongs on Empty; host-branch Loading / Empty / Error per Page And Region Status.
When To Use
- Show a full-page outcome after submit, create, or a hard failure (404, 403, 500).
- Place recovery actions inline in
extra— not in a docked footer. - Use
size="region"when an embedded panel needs a compact load-failure block (status="error"+ Retry). - Use Empty for successful no-content; branch Loading / Empty / Error yourself per Page And Region Status — do not use Result as Empty.
- Do not use Result for toast feedback or for a populated list/detail body.
Features
| Area | Behavior |
|---|---|
| Status | success · error · info · 403 · 404 · 500 with default Lucide icons |
| Size | page (default) — tall min-height and large icon; region — compact padding and smaller icon |
| Placement | Centered chrome; do not grow (flex-1) by default. List / Related List containers opt in. See Page And Region Status |
| Copy | Host-supplied title / subTitle (no built-in i18n strings) |
| Actions | extra row for primary/secondary buttons (Retry, Back, View…) |
| Icon override | Pass icon to replace the default status circle |
| Slots | classNames for root · icon · title · subTitle · extra |
Installing
pnpm dlx shadcn@latest add https://ui.isaacfei.com/r/result.jsonnpx shadcn@latest add https://ui.isaacfei.com/r/result.jsonyarn dlx shadcn@latest add https://ui.isaacfei.com/r/result.jsonbun x shadcn@latest add https://ui.isaacfei.com/r/result.jsonWith a namespace: npx shadcn@latest add @f-ui/result.
registryDependencies: utils. Runtime: lucide-react.
Usage
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
<Result
status="404"
title="Page not found"
subTitle="The page you requested does not exist."
extra={<Button type="button">Back home</Button>}
/>;Examples
Success
Default size="page" with a success status and two recovery actions — the usual full-page band after a submit.
Order submitted
We sent a confirmation email. You can track progress from Orders.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function ResultDemo() {
return (
<Result
status="success"
title="Order submitted"
subTitle="We sent a confirmation email. You can track progress from Orders."
extra={
<>
<Button type="button">View order</Button>
<Button type="button" variant="outline">
Back to list
</Button>
</>
}
/>
);
}Forbidden
403 when the signed-in user is not allowed to open the resource. Offer a clear way back.
Access denied
Sorry, you are not authorized to access this page.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function Result403Demo() {
return (
<Result
status="403"
title="Access denied"
subTitle="Sorry, you are not authorized to access this page."
extra={
<Button type="button" variant="outline">
Back home
</Button>
}
/>
);
}Page Not Found
404 for a missing route or deleted resource. Keep recovery simple — usually Back home.
Page not found
Sorry, the page you visited does not exist.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function Result404Demo() {
return (
<Result
status="404"
title="Page not found"
subTitle="Sorry, the page you visited does not exist."
extra={
<Button type="button" variant="outline">
Back home
</Button>
}
/>
);
}Server Error
500 when the server failed and the user should leave or retry later from a safe entry point.
Something went wrong
Sorry, the server is reporting an error.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function Result500Demo() {
return (
<Result
status="500"
title="Something went wrong"
subTitle="Sorry, the server is reporting an error."
extra={
<Button type="button" variant="outline">
Back home
</Button>
}
/>
);
}Submit Error
Page-scale status="error" after a form submit fails — fix-and-resubmit plus a secondary escape hatch.
Submission failed
Please check the form and try again.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function ResultSubmitErrorDemo() {
return (
<Result
status="error"
title="Submission failed"
subTitle="Please check the form and try again."
extra={
<>
<Button type="button">Fix and resubmit</Button>
<Button type="button" variant="outline">
Back to list
</Button>
</>
}
/>
);
}Region Load Failure
size="region" drops the page min-height and uses a smaller icon so a load failure fits inside a card or panel. Pair with Retry in extra. Successful empty regions use Empty, not Result.
Could not load files
Check your connection and try again.
"use client";
import { Result } from "@/components/f-ui/result/result";
import { Button } from "@/components/ui/button";
export function ResultRegionDemo() {
return (
<div className="rounded-xl border bg-card">
<Result
size="region"
status="error"
title="Could not load files"
subTitle="Check your connection and try again."
extra={
<Button type="button" variant="outline">
Retry
</Button>
}
/>
</div>
);
}Composition
Result
├── icon circle (default status Lucide, or `icon` prop)
├── title (h2)
├── subTitle (optional)
└── extra (optional action row)Compose under Page Container with surface="plain" and often fixedHeader={false} for page outcomes.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
status | "403" | "404" | "500" | "success" | "error" | "info" | — | Selects the default icon and tone |
title | ReactNode | — | Primary heading |
subTitle | ReactNode | — | Supporting copy under the title |
extra | ReactNode | — | Inline recovery actions |
icon | ReactNode | status default | Replaces the default status icon circle |
size | "page" | "region" | "page" | Page band vs compact in-panel layout |
className | string | — | Extra classes on the root |
classNames | ResultClassNames | — | Per-slot class overrides |
Slots
| Slot | Element |
|---|---|
root | Outer data-slot="result" container |
icon | Default icon circle wrapper |
title | Heading |
subTitle | Subtitle paragraph |
extra | Actions row |