Stop 12 · AuthenticationTopics · 8/10

Protected Routes

Part of the Frontend Developer Roadmap

In short

Your /dashboard shouldn't open for someone who just typed the URL. Protected routes check who's asking before showing anything, and the check must happen where users can't skip it.

Pages or routes that should only be accessible to authenticated (or authorized) users, redirecting everyone else to a login page.

The jaadu as a ticket examiner checks a passenger's ticket inside an AC train coach.

Think of it like this

The TTE in the AC coach

Anyone can walk onto the platform. But inside the AC coach, the TTE checks your ticket and sends you out if you don't have one. Hiding the coach door wouldn't help. The ticket check on board is what really protects the seats.

Watch it happen

Opening /dashboard without logging in

Visitor
proxy.ts
Dashboard
API

GET /dashboard

1/6The visitor types the URL directly. The proxy runs before any page code.

The big ideas

What you need to know

Hiding a link isn't protection

Removing the Dashboard link from the navbar is nice UX. Anyone can still type the URL.

Check early with the proxy

In Next.js, proxy.ts (middleware.ts before v16) can redirect visitors without a session cookie before the page even renders.

Check again near the data

Verify the session inside the page or API route too. The proxy is a fast first gate, not the only one.

Remember where they were going

Redirect to /login?next=/dashboard so you can send them back after they log in.

See it in code

Walk through the code

ts
1// proxy.ts (Next.js 16; called middleware.ts in older versions)2import { NextResponse, type NextRequest } from "next/server";3 4export function proxy(req: NextRequest) {5  const hasSession = req.cookies.has("session");6  if (!hasSession) {7    const url = new URL("/login", req.url);8    url.searchParams.set("next", req.nextUrl.pathname);9    return NextResponse.redirect(url);10  }11  return NextResponse.next();12}13 14export const config = { matcher: ["/dashboard/:path*", "/settings/:path*"] };

1/4The proxy runs on matching requests and checks if a session cookie exists.

This only checks that a cookie exists, which is a quick optimistic check. The page or API must still verify that the session inside it is valid.

Save yourself the pain

Common mistakes

Oops

Protecting the page but leaving /api/orders open.

Do this instead

Every API route that returns private data needs its own session check. Attackers call APIs directly.

Oops

Redirecting to whatever ?next= says without checking it.

Do this instead

Only allow paths that start with a single /. Otherwise attackers can bounce your users to a phishing site.

Your mission

Lock the dashboard

~30 min

Quick check

You hid the Admin link for normal users, but one of them opens /admin by typing it. What actually stops them?

Go deeper

  1. 1Build a route guard that redirects unauthenticated users to `/login`.
  2. 2Implement this via middleware in Next.js rather than only client-side checks.
  3. 3Remember: client-side route protection is a UX nicety — the API must enforce it too.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge