Permission-denied page for team apps: an accent lock chip and bold headline on the left, the signed-in account card with an account switch link and a square-bullet list of access requirements on the right.
A permission-denied page for team apps: an accent lock chip and headline with a request button on the left, the signed-in account card and a square-bullet list of what actually unlocks the page on the right.
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/error16?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/error16?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/error16.tsx, plus the two design-system primitives it renders through: badge6 for the square eyebrow and button1 for the seal call to action.
The installed file exports error16Demo alongside the block: the exact props behind the preview above. Spread it to get a working permission page in one line.
import { Error16, error16Demo } from "@/components/beste/block/error16";
export default function Forbidden() {
return <Error16 {...error16Demo} />;
}Then pass the real session so the card shows who is actually signed in:
import { Error16 } from "@/components/beste/block/error16";
export default function Forbidden({ user }: { user: { name: string; email: string; image: string } }) {
return (
<Error16
label="Access Denied"
code="403"
heading="This workspace is <strong>closed to you</strong>, for now."
description="Your account is signed in, it simply has not been granted a seat here."
labels={{ signedInAs: "Signed in as", requirementsTitle: "What unlocks this page" }}
account={{
name: user.name,
email: user.email,
avatar: { src: user.image, alt: "Portrait of the signed-in account holder" },
}}
switchLink={{ label: "Use a different account", href: "/sign-in" }}
requirements={[
"A seat on the workspace, granted by any owner",
"Single sign-on through your company domain",
]}
button={{ label: "Request a seat", href: "/request-access" }}
link={{ label: "Back to your dashboard", href: "/app" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
label | string | – | Eyebrow text rendered through the square-marker badge |
code | string | – | Status code shown after the eyebrow divider |
heading | string | – | Headline HTML, rendered as an h1; <strong> marks the accent clause |
description | string | – | Explanatory paragraph under the headline |
labels | Error16Labels | {} | Captions for the account card and the requirements list |
account | AccountInfo | – | The signed-in account shown in the card |
switchLink | ActionLink | – | Account switch link inside the card |
requirements | string[] | [] | Square-bullet list of access requirements |
button | ActionLink | – | Seal call to action under the description |
link | ActionLink | – | Text link beside the call to action |
className | string | – | Extra classes for the outer <section> |
type Error16Labels = {
signedInAs?: string;
requirementsTitle?: string;
};
type AccountInfo = {
name: string;
email: string;
avatar: { src: string; alt: string };
};
type ActionLink = {
label: string;
href: string;
};lg breakpoint, where the message and the account panel split into two columns.heading is injected with dangerouslySetInnerHTML and accepts inline HTML; <strong> takes the accent colour. Keep the value under your own control, never user input.error23
Monochrome permission page: a display headline over a request pill that swaps to a sent confirmation, a ruled record of the project, owner and visibility, and an overlapping avatar row of current members.
error26
Billing lockout page: an accent card chip and headline with an update-payment seal button on the left, an unpaid invoice table and a square-bullet list of what stays untouched on the right.
error28
Geo-restriction page: an accent globe chip and headline, the detected region in a bordered strip, a two-column ruled list of markets with their rollout status, and a notify-me seal button.
error27
Timed-out session page: an accent headline over an account strip showing the avatar, address and sign-out timestamp, an autosave reassurance line, and a sign-in seal button beside an account switch link.
error7
Compact bordered 404 card with a circular icon, status label, heading, one-line explanation, and stacked full-width buttons. Sized for app shells and modals as well as full pages.
error15
Server error page with a square eyebrow and status code over a hairline rule, a bold accent headline, a bordered incident table of reference, timestamp and service rows, and a retry seal button beside a status page link.