Protected Routes (Frontend)
Part of the Full Stack 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.
Redirecting unauthenticated users away from pages that require login — a UX nicety on the frontend that must always be backed by real enforcement on the backend.

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
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
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
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
- 1Build a route wrapper that redirects to `/login` if no valid token/session exists.
- 2Show a loading state while the auth check happens, to avoid a flash of protected content.
- 3Remember this is only a UX layer — never rely on it for actual security.
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.