Bird
Raised Fist0
NextJSframework~15 mins

Conditional routes in NextJS - Deep Dive

Choose your learning style10 modes available
Overview - Conditional routes
What is it?
Conditional routes in Next.js let you decide which pages or components to show based on certain conditions like user login status or permissions. Instead of always showing the same page, the app can change what the user sees depending on their situation. This helps create personalized and secure experiences in web apps. It works by checking conditions during rendering or navigation and then choosing the right route or content.
Why it matters
Without conditional routes, every user would see the same pages regardless of who they are or what they can do. This means no private areas, no user-specific content, and poor user experience. Conditional routing solves this by controlling access and tailoring content, making apps feel smart and safe. It also helps protect sensitive data and guides users smoothly through the app based on their status.
Where it fits
Before learning conditional routes, you should understand basic Next.js routing and React components. After mastering conditional routes, you can explore advanced authentication flows, middleware for route protection, and dynamic routing patterns. This topic fits in the journey after learning how Next.js pages and navigation work and before building full user authentication systems.
Mental Model
Core Idea
Conditional routes are like traffic signals that decide which path a user takes in an app based on who they are or what they need.
Think of it like...
Imagine a theme park with different rides. Some rides are only for adults, some for kids, and some for everyone. Conditional routes are like the park staff who check your ticket and age, then guide you to the rides you can enjoy safely.
┌───────────────┐
│ User Requests │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Check Condition│
│ (e.g., logged in)│
└──────┬────────┘
       │Yes / No
       │       
  ┌────▼─────┐ ┌────▼─────┐
  │ Route A  │ │ Route B  │
  │ (Allowed)│ │(Redirect)│
  └──────────┘ └──────────┘
Build-Up - 6 Steps
1
FoundationBasic Next.js Routing
🤔
Concept: Learn how Next.js handles routing with its file-based system.
In Next.js, every file inside the 'pages' folder automatically becomes a route. For example, 'pages/index.js' is the home page at '/', and 'pages/about.js' is at '/about'. You navigate between pages using the Link component or router methods.
Result
You can create multiple pages and navigate between them with simple URLs.
Understanding the automatic routing system is essential before adding conditions to routes.
2
FoundationRendering Components Conditionally
🤔
Concept: Learn how to show or hide parts of a page based on simple conditions.
In React, you can use JavaScript conditions inside components to decide what to show. For example, if a user is logged in, show a welcome message; if not, show a login button. This is done using if statements or ternary operators inside JSX.
Result
Pages can display different content without changing routes.
Conditional rendering inside components is the building block for conditional routing.
3
IntermediateRedirecting Based on User State
🤔Before reading on: do you think redirecting users happens automatically or requires explicit code? Commit to your answer.
Concept: Learn how to send users to different pages depending on conditions like login status.
Next.js provides the 'useRouter' hook to programmatically navigate users. For example, if a user is not logged in, you can redirect them from a protected page to the login page using 'router.push('/login')' inside a useEffect hook.
Result
Users trying to access protected pages get sent to the right place automatically.
Knowing how to redirect users programmatically is key to controlling access in apps.
4
IntermediateProtecting Pages with Server-Side Checks
🤔Before reading on: do you think client-side checks alone are enough to secure pages? Commit to your answer.
Concept: Learn how to check user permissions on the server before rendering pages.
Next.js supports server-side rendering with functions like 'getServerSideProps'. You can check if a user is authenticated on the server, and if not, redirect them before the page loads. This prevents unauthorized users from even seeing protected content.
Result
Pages are secured by server checks, improving security and user experience.
Server-side checks prevent unauthorized access better than client-only methods.
5
AdvancedUsing Middleware for Route Control
🤔Before reading on: do you think middleware runs before or after page rendering? Commit to your answer.
Concept: Learn how Next.js middleware can intercept requests and control routing before pages load.
Middleware in Next.js runs before a request reaches a page. You can write middleware to check cookies or tokens and redirect users if they lack permission. This runs on the edge, making routing decisions faster and more secure.
Result
Routing decisions happen early, improving performance and security.
Middleware offers a powerful way to centralize route protection and reduce repeated code.
6
ExpertDynamic Conditional Routes with Client and Server Sync
🤔Before reading on: do you think client and server states always match perfectly? Commit to your answer.
Concept: Learn how to keep client and server conditions in sync for seamless conditional routing.
In complex apps, user state can change on the client or server. Using tools like React Context or SWR for data fetching, combined with server-side checks and middleware, helps keep routing decisions consistent. Handling edge cases like token expiration or network delays requires careful coordination.
Result
Users experience smooth navigation with accurate access control.
Understanding the interplay between client and server states prevents bugs and security holes in conditional routing.
Under the Hood
Next.js routing is based on the file system, where each page file maps to a URL path. Conditional routes work by adding logic either on the client side (React components and hooks) or server side (getServerSideProps, middleware). Middleware runs before the request reaches the page, allowing early interception. Client-side redirects use the router API to change the URL without full reloads. Server-side redirects send HTTP status codes to instruct the browser to navigate elsewhere. This layered approach balances user experience and security.
Why designed this way?
Next.js was designed to simplify routing by using the file system, making it easy for beginners. Conditional routing needed to fit naturally into this system without complicating the developer experience. Middleware was introduced to handle edge cases and improve performance by running at the edge before pages load. Server-side checks ensure security by preventing unauthorized data exposure. This design balances simplicity, flexibility, and security.
┌───────────────┐
│ Incoming HTTP │
│   Request     │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│  Middleware   │
│ (Edge Logic)  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Server-side   │
│  Rendering    │
│ (getServerSideProps)│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Client-side   │
│  React Logic  │
│ (useRouter,   │
│  useEffect)   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do client-side redirects alone fully protect private pages? Commit to yes or no.
Common Belief:Client-side redirects are enough to secure private pages.
Tap to reveal reality
Reality:Client-side redirects can be bypassed, so server-side checks or middleware are needed for real security.
Why it matters:Relying only on client-side redirects can expose sensitive data to unauthorized users.
Quick: Do you think middleware runs after the page loads? Commit to yes or no.
Common Belief:Middleware runs after the page has loaded to adjust content.
Tap to reveal reality
Reality:Middleware runs before the page loads, intercepting requests early.
Why it matters:Misunderstanding middleware timing can lead to incorrect assumptions about security and performance.
Quick: Is it true that conditional routes always slow down your app? Commit to yes or no.
Common Belief:Adding conditional routes always makes the app slower.
Tap to reveal reality
Reality:When done properly with middleware and server-side checks, conditional routing can improve user experience without noticeable slowdowns.
Why it matters:Avoiding conditional routes out of fear of slowness can limit app functionality and security.
Quick: Do you think client and server user states always match perfectly? Commit to yes or no.
Common Belief:Client and server user states are always in sync automatically.
Tap to reveal reality
Reality:They can differ due to delays or token expiration, requiring careful syncing strategies.
Why it matters:Ignoring state mismatches can cause confusing bugs and security risks.
Expert Zone
1
Middleware runs on the edge network, so it must be lightweight and fast to avoid slowing requests.
2
Using getServerSideProps for auth checks can impact caching and performance, so balance security needs with speed.
3
Client-side redirects can cause flickering if server-side checks are missing, harming user experience.
When NOT to use
Conditional routes are not ideal for static sites where content is public and unchanging; instead, use static generation. Also, avoid complex client-only conditional routing for sensitive data; prefer server-side or middleware checks. For very large apps, consider dedicated auth libraries or backend services for routing control.
Production Patterns
In production, apps often combine middleware for early redirects, server-side props for secure data fetching, and client-side hooks for UI changes. Role-based access control is implemented by checking user roles in middleware and server functions. Progressive enhancement ensures users without JavaScript still get proper redirects via server logic.
Connections
Access Control Lists (ACL)
Conditional routes implement ACL principles by controlling who can access what.
Understanding ACL helps grasp why conditional routes check permissions before allowing access.
State Machines
Conditional routing can be seen as a state machine where user state determines the next route.
Viewing routing as state transitions clarifies how apps manage complex navigation flows.
Traffic Signal Systems
Both control flow based on conditions to ensure safe and orderly movement.
Recognizing this shared pattern helps design routing logic that prevents conflicts and errors.
Common Pitfalls
#1Trying to protect pages only with client-side redirects.
Wrong approach:useEffect(() => { if (!user) router.push('/login'); }, []); // client-only redirect
Correct approach:export async function getServerSideProps(context) { const user = /* get user from context */; if (!user) { return { redirect: { destination: '/login', permanent: false } }; } return { props: {} }; }
Root cause:Believing client-side code alone can secure pages ignores that users can bypass it by disabling JavaScript or inspecting network requests.
#2Placing heavy logic inside middleware causing slow responses.
Wrong approach:Middleware runs complex database queries or long computations.
Correct approach:Middleware only checks tokens or cookies and redirects; heavy logic runs in server-side functions.
Root cause:Misunderstanding middleware's role and performance constraints leads to slow app behavior.
#3Assuming user state is always current on the client.
Wrong approach:Rendering protected content immediately after login without verifying token validity.
Correct approach:Use SWR or React Query to fetch fresh user data and verify tokens before rendering sensitive content.
Root cause:Overlooking asynchronous state changes and token expiration causes security holes and UI glitches.
Key Takeaways
Conditional routes let apps show different pages or content based on user status or permissions.
Next.js supports conditional routing through client-side logic, server-side checks, and middleware for best security and performance.
Relying only on client-side redirects is insecure; server-side or middleware checks are essential.
Middleware runs before pages load, enabling fast and centralized route control.
Keeping client and server user states in sync is crucial to avoid bugs and security issues.

Practice

(1/5)
1. What is the main purpose of conditional routes in Next.js?
easy
A. To create static pages only
B. To style pages differently
C. To fetch data from an API
D. To control access and redirect users based on conditions

Solution

  1. Step 1: Understand conditional routes concept

    Conditional routes let you decide which users can see certain pages or redirect them elsewhere.
  2. Step 2: Identify the purpose in Next.js

    Next.js uses conditional routes mainly to protect pages or redirect users based on login or roles.
  3. Final Answer:

    To control access and redirect users based on conditions -> Option D
  4. Quick Check:

    Conditional routes = control access [OK]
Hint: Think: Who should see this page? Redirect if no permission. [OK]
Common Mistakes:
  • Confusing conditional routes with styling or data fetching
  • Thinking conditional routes create static pages
  • Believing conditional routes only fetch data
2. Which Next.js hook is commonly used to perform client-side redirects in conditional routes?
easy
A. useState
B. useEffect
C. useRouter
D. useContext

Solution

  1. Step 1: Identify hooks for routing

    Next.js provides useRouter to access routing methods like push for redirects.
  2. Step 2: Confirm redirect usage

    While useEffect runs side effects, useRouter is needed to actually change routes.
  3. Final Answer:

    useRouter -> Option C
  4. Quick Check:

    Redirects use useRouter [OK]
Hint: Redirects need router methods, so useRouter is key. [OK]
Common Mistakes:
  • Using useState to redirect (it manages state only)
  • Confusing useEffect as the hook that changes routes
  • Thinking useContext handles routing
3. Given this Next.js component, what will happen if isLoggedIn is false?
import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function Dashboard() {
  const router = useRouter();
  const isLoggedIn = false;

  useEffect(() => {
    if (!isLoggedIn) {
      router.push('/login');
    }
  }, [isLoggedIn]);

  return <h1>Dashboard</h1>;
}
medium
A. The user is redirected to the /login page
B. The page reloads infinitely
C. The page shows an error
D. The user stays on the Dashboard page

Solution

  1. Step 1: Analyze the useEffect condition

    The effect checks if isLoggedIn is false, then calls router.push('/login').
  2. Step 2: Understand router.push behavior

    This causes a client-side redirect to the login page when not logged in.
  3. Final Answer:

    The user is redirected to the /login page -> Option A
  4. Quick Check:

    False login triggers redirect [OK]
Hint: False login triggers router.push to /login. [OK]
Common Mistakes:
  • Thinking the user stays on Dashboard despite redirect
  • Assuming an error occurs without redirect
  • Believing infinite reload happens here
4. Identify the error in this Next.js conditional route code:
import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function Profile() {
  const router = useRouter();
  const isAuthorized = false;

  if (!isAuthorized) {
    router.push('/unauthorized');
  }

  return <h1>Profile</h1>;
}
medium
A. Calling router.push inside the component body causes an error
B. Missing dependency array in useEffect
C. useRouter is not imported correctly
D. The component returns invalid JSX

Solution

  1. Step 1: Check where router.push is called

    router.push is called directly inside the component body, which runs on every render and is not allowed.
  2. Step 2: Correct usage with useEffect

    Redirects should be inside useEffect to avoid infinite loops or errors.
  3. Final Answer:

    Calling router.push inside the component body causes an error -> Option A
  4. Quick Check:

    Redirects must be inside useEffect [OK]
Hint: Put router.push inside useEffect, not directly in component body. [OK]
Common Mistakes:
  • Calling router.push directly in component body
  • Ignoring useEffect for side effects
  • Assuming missing import causes error here
5. You want to create a Next.js page that only logged-in users can access. If the user is not logged in, redirect them to '/login'. Which is the best approach?
1. Use useRouter and useEffect to check login and redirect client-side.
2. Use Next.js middleware to check authentication before rendering.
3. Render a loading state while checking login status.
4. Avoid rendering protected content until login is confirmed.
Which combination correctly applies conditional routing best practice?
hard
A. Only 1 and 2
B. All 1, 2, 3, and 4
C. Only 2 and 4
D. Only 1, 3, and 4

Solution

  1. Step 1: Understand client-side and server-side checks

    Client-side redirect with useRouter/useEffect (1) is common, but middleware (2) adds server-side protection.
  2. Step 2: Consider user experience

    Showing a loading state (3) and avoiding rendering protected content before login confirmation (4) improve UX and prevent flicker.
  3. Step 3: Combine all for best practice

    Using all four ensures secure, smooth conditional routing in Next.js.
  4. Final Answer:

    All 1, 2, 3, and 4 -> Option B
  5. Quick Check:

    Best practice = all steps combined [OK]
Hint: Combine client, server checks and loading states for best routing. [OK]
Common Mistakes:
  • Relying only on client-side redirects
  • Skipping loading states causing flicker
  • Ignoring server-side middleware protection
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard