01 / 02

How do you implement role-based route protection — what's the difference between doing it in middleware vs layout vs page?

Difficulty: 5/10
middleware, layout, page protection

Role-based route protection in Next.js can be implemented at three levels — Middleware, Layout, and Page. Each has different capabilities, trade-offs, and ideal use cases. Middleware runs earliest at the Edge before any rendering, Layout protects entire route segments with server-side data access, and Page gives the most granular per-page control. The best production apps combine all three layers as a defense-in-depth strategy.

Think of role-based protection as layers of security. Middleware is the bouncer at the front door — fast, early, but limited in what it can verify. Layout is the security desk inside — has access to your full database and session. Page is the room itself — most granular, knows exactly what content to show or hide per role. Using only one layer is fragile. Using all three together creates a robust, secure, and performant protection system.

The Three Layers of Protection
  1. 1

    Middleware — runs at Edge before rendering, best for fast redirects based on token/cookie presence

  2. 2

    Layout — runs on server with full DB access, best for role verification across route segments

  3. 3

    Page — runs on server or client, best for granular per-page role checks and UI-level protection

Layer 1 — Middleware Protection (Edge Level)
Layer 2 — Layout Protection (Server Component Level)
Layer 3 — Page Level Protection (Most Granular)
Reusable Auth Helper — Used Across Layouts and Pages
Client Component Role Gating — UI Level
Complete Defense-in-Depth Example
Middleware vs Layout vs Page — Side by Side
  1. 1

    Middleware — runs at Edge before rendering, fastest, no DB access, best for token/cookie presence checks

  2. 2

    Middleware — can redirect before any HTML is generated, lowest latency protection

  3. 3

    Middleware — cannot verify role from DB, only from JWT claims (which can be stale)

  4. 4

    Layout — runs on server with full DB and session access, protects entire route segments

  5. 5

    Layout — re-runs only when segment mounts, not on every child navigation

  6. 6

    Layout — best for segment-level protection where all child routes need same role

  7. 7

    Page — most granular, per-page permission checks with specific data scoping

  8. 8

    Page — can use notFound() to hide existence of a page entirely from unauthorized users

  9. 9

    Page — UI-level gating to show/hide buttons and sections based on permissions

Critical Security Rules
  1. 1

    Never rely on client-side role checks alone — always back up with server-side verification

  2. 2

    Never trust JWT role claims without DB verification for sensitive operations — roles can change

  3. 3

    Use notFound() instead of redirect('/forbidden') to hide existence of sensitive pages

  4. 4

    Always scope data queries to the authenticated user — never return data outside their org/tenant

  5. 5

    Middleware alone is not enough — JWT can be stale if role changed after token was issued

  6. 6

    Defense in depth — always use at least two layers (middleware + layout or middleware + page)

  7. 7

    Log all unauthorized access attempts for security auditing

Scenario Questions

0-2 years experience

  1. 1We have a Next.js app with an `/admin` page that should only be visible to users with the 'admin' role. How would you protect that route using Next.js middleware?
  2. 2If you placed a role check inside the page component's `getServerSideProps` instead of middleware, what would happen when a non‑admin user navigates to `/admin`?
  3. 3What steps would you take to redirect an unauthorized user to a login page from middleware?

2-5 years experience

  1. 1Your team wants to protect several sections like `/dashboard` and `/settings` based on user roles, but some pages also need layout‑specific UI changes for unauthorized users. How would you decide whether to put the role check in middleware, a shared layout, or individual pages? Walk through the trade‑offs.
  2. 2During a recent release, a bug appeared where users with the correct role still saw a 404 on a protected page. The middleware logs show the role was present. What could cause this, and how would you debug it?
  3. 3Explain how you would handle role changes that happen client‑side (e.g., after a user upgrades) without a full page reload. Which layer would you update and why?

5-8 years experience

  1. 1Design a scalable role‑based protection system for a large Next.js monorepo where some routes are static, some are server‑rendered, and some are API routes. Discuss where you would place the checks, how you’d share logic, and how you’d avoid duplication.
  2. 2Consider performance: middleware runs on every request, while layout runs after the page is rendered. How would you evaluate the impact on latency and caching for a high‑traffic site, and what optimizations would you apply?
  3. 3Your application must support per‑tenant custom roles that can be added at runtime. How would you extend the existing middleware/layout approach to accommodate dynamic role definitions without redeploying?

8+ years experience

  1. 1The company is migrating a legacy Express app to Next.js and wants a unified role‑based access control across both front‑end routes and backend APIs. Propose an architecture that allows shared policy definitions, minimal code churn, and consistent enforcement across middleware, layouts, and API routes.
  2. 2Across multiple teams, there are conflicting conventions: some use middleware, others use layout, leading to duplicated checks and security gaps. How would you lead a cross‑team effort to standardize role protection, including guidelines, tooling, and a migration plan?
  3. 3Discuss the long‑term maintenance implications of embedding role logic in page components versus a centralized middleware. Which strategy better supports feature flagging, audit logging, and compliance requirements at scale?

Follow-up Questions

  • What would you do if the role information is only available after an async call?
  • How does Edge Middleware change the way you implement role checks?
  • Can you think of any security risks if the check lives only on the client side?
Share

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.