Protected Layout
A copy-paste React access screen for a Next.js layout or app root — header and footer stay visible while locked. Zero dependencies.
Best used for A Next.js layout.tsx or app root where the header/footer must survive the locked state.
Built for a Next.js layout.tsx or any app root where the gate should wrap the page content but not the
site chrome around it.
Minimal setup
<ProtectedLayout expectedHash={process.env.NEXT_PUBLIC_KNOCK_HASH} header={<SiteHeader />}>
<YourApp />
</ProtectedLayout>
- components
- knock-codes
- core
- react
"use client";
import type { ReactNode } from "react";
import { KnockCodes, type KnockCodesProps } from "./KnockCodes.tsx";
export interface ProtectedLayoutProps extends KnockCodesProps {
/** Rendered above the PIN prompt even while locked — e.g. a persistent site header/logo. */
header?: ReactNode;
/** Rendered below the PIN prompt even while locked. */
footer?: ReactNode;
}
/**
* `<KnockCodes>` shaped for a full-page shell (a Next.js `layout.tsx`, an
* app root): `header`/`footer` render unconditionally, so persistent site
* chrome (logo, footer links) survives the gate instead of disappearing
* behind it while locked.
*/
export function ProtectedLayout({ header, footer, children, ...props }: ProtectedLayoutProps) {
return (
<>
{header}
<KnockCodes {...props}>{children}</KnockCodes>
{footer}
</>
);
}
Add this block to your project
Recommended
npx shadcn@latest add @knock-codes/protected-layoutAlso installs
- Knock Codes Core
- Knock Codes Types
- useKnockCodes
- cx (classname helper)
- Gate Wrapper
- PIN Input
- Knock Codes
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 (12)
- components/knock-codes/core/hash.ts
- components/knock-codes/core/verify.ts
- components/knock-codes/core/session.ts
- components/knock-codes/core/storage.ts
- components/knock-codes/react/types.ts
- components/knock-codes/react/useKnockCodes.ts
- components/knock-codes/react/KnockCodesContext.tsx
- components/knock-codes/react/cx.ts
- components/knock-codes/react/GateWrapper.tsx
- components/knock-codes/react/PinInput.tsx
- components/knock-codes/react/KnockCodes.tsx
- components/knock-codes/react/ProtectedLayout.tsx
Other ways
GitHub shorthand
npx shadcn@latest add trivedi-vatsal/knock-codes/protected-layoutCopy the files by hand
- Open the Code tab in the preview above.
- Create each path listed below in your project and paste its contents in.
- Do the same for anything listed under “Also installs”, if present.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| expectedHash | string | — | SHA-256 hex hash to verify against, for local mode. |
| verify | VerifyFn | — | Custom async verification function, for server mode. |
| children * | ReactNode | — | Rendered once unlocked. |
| header | ReactNode | — | Rendered above the access-code prompt even while locked. |
| footer | ReactNode | — | Rendered below the access-code prompt even while locked. |
Exactly one of expectedHash or verify is required.
Accessibility
Header and footer are always in the document, in source order, whether or not the gate is unlocked — so a persistent nav landmark stays reachable by screen reader users at every state, not just once unlocked.
Customization
Pass `header`/`footer` for chrome that should survive the gate — a logo, a footer with legal links. Everything else (labels, storage, timeout) is identical to Knock Codes.
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.
Used in these templates
Want the whole screen instead of assembling it yourself? These templates already build on this block.
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.
- Knock CodesA copy-paste React access screen for gating a whole page or app root — local hash or server verification, one prop swap between them. Zero dependencies.
- Protected RouteA copy-paste React access screen for route-level guarding — React Router or similar, with an optional custom denial state. Zero dependencies.
- Standalone GateA copy-paste React access screen for the fastest possible integration — wrap your app, pass a hash, done. Zero dependencies.