Skip to content

Access Denied Screen

A copy-paste React denial screen for a hard-locked route or a custom Protected Route fallback — no access-code form, no retry. Zero dependencies.

FeedbackUtilityfeedbackfallback

Best used for A hard-denial state after too many failed attempts, or a custom unauthorizedFallback on Protected Route.

Distinct from the access-code entry UI <KnockCodes> renders while locked — this screen means "no more attempts," not "try again."

// Usage

Minimal setup

<ProtectedRoute
  expectedHash={process.env.NEXT_PUBLIC_KNOCK_HASH}
  unauthorizedFallback={<AccessDeniedScreen action={<a href="/contact">Contact us</a>} />}
>
  <Dashboard />
</ProtectedRoute>

Access denied

You don't have permission to view this page.

Installation

Add this block to your project

Recommended

npx shadcn@latest add @knock-codes/access-denied-screen

Also installs

  • cx (classname helper)
  • Gate Wrapper

These install together as one atomic unit — even a presentational or read-only piece needs the full verification stack (hook, types, core) behind it to actually run.

Files created (3)

  • components/knock-codes/react/cx.ts
  • components/knock-codes/react/GateWrapper.tsx
  • components/knock-codes/react/AccessDeniedScreen.tsx
Other ways

GitHub shorthand

npx shadcn@latest add trivedi-vatsal/knock-codes/access-denied-screen

Copy the files by hand

  1. Open the Code tab in the preview above.
  2. Create each path listed below in your project and paste its contents in.
  3. Do the same for anything listed under “Also installs”, if present.
// Props

API reference

PropTypeDefaultDescription
headingstring"Access denied"The main heading.
messageReactNode"You don’t have permission to view this page."Body copy under the heading.
actionReactNodeOptional call to action under the message.
variant"page" | "inline""page"Outer positioning.
Notes

Accessibility

A plain heading + message + optional action — no live region needed since nothing here changes without a full re-render triggered by the parent.

Customization

Not wired to any verification strategy on purpose. Use it as a custom `unauthorizedFallback` on `<ProtectedRoute>`, or anywhere you need a denial state that never accepts another attempt — pass `action` for a "contact us" link or a retry button that resets your own flow.

Security & Verification

Need a hash? Use the hash generator on Getting Started — computed locally, never sent anywhere.

The honest version

Knock Codes stops casual visitors, search engines, and forwarded links. Local mode does not stop anyone who opens DevTools — the hash ships in your client bundle by design. Server mode (swap one prop) hides the hash from the client; children you already bundled are still in the JavaScript, and a forged session works unless you wire validateSession. A velvet rope, with an optional real lock. Never marketed as more than that.

// Compose with

Blocks that pair well with this one

These combine naturally with this block, whether as a shared shell, a shared session, or a common fallback.