403 Access Request

Access Denied
403

This workspace is closed to you, for now.

Your account is signed in and healthy, it simply has not been granted a seat here. Ask an owner for access and you will be through in minutes.

What unlocks this page

  • A seat on the workspace, granted by any owner
  • The billing plan that includes shared projects
  • Single sign-on through your company domain
About this block

403 Access RequestPRO

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.

Error16: 403 Access Request

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.

Upgrade to Pro

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.

Upgrade Now

Installation

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

bash
npx shadcn add "https://ui.beste.co/r/error16?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
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.

Quick start

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.

tsx
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:

tsx
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" }}
    />
  );
}

Props

PropTypeDefaultDescription
labelstring–Eyebrow text rendered through the square-marker badge
codestring–Status code shown after the eyebrow divider
headingstring–Headline HTML, rendered as an h1; <strong> marks the accent clause
descriptionstring–Explanatory paragraph under the headline
labelsError16Labels{}Captions for the account card and the requirements list
accountAccountInfo–The signed-in account shown in the card
switchLinkActionLink–Account switch link inside the card
requirementsstring[][]Square-bullet list of access requirements
buttonActionLink–Seal call to action under the description
linkActionLink–Text link beside the call to action
classNamestring–Extra classes for the outer <section>
ts
type Error16Labels = {
  signedInAs?: string;
  requirementsTitle?: string;
};

type AccountInfo = {
  name: string;
  email: string;
  avatar: { src: string; alt: string };
};

type ActionLink = {
  label: string;
  href: string;
};

Behavior notes

  • The account card and the requirements list are independent: either can be omitted, and the right column simply collapses to whichever one is passed.
  • Long addresses truncate inside the card with an ellipsis rather than widening the column or wrapping under the avatar.
  • The layout is a single column until the 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.
  • Everything is static markup with no client state, so the page renders on the server and works with JavaScript disabled.

More Error blocks

View all Error
PRO

error23

Invitation Only Access

PRO

error37

Access Denied With Request Path

PRO

error26

Payment Required Lockout

Get Pro access