Bird
Raised Fist0
NextJSframework~20 mins

Protected routes with middleware in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Next.js Middleware Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What happens when an unauthenticated user accesses a protected route?

Consider a Next.js app using middleware to protect routes under /dashboard. The middleware checks for a valid token cookie. What is the expected behavior when a user without a token tries to access /dashboard/profile?

NextJS
import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('token')?.value;
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: '/dashboard/:path*',
};
AThe user is redirected to the /login page.
BThe user is shown a 404 Not Found error.
CThe middleware throws a runtime error due to missing token.
DThe user sees the dashboard page content without restrictions.
Attempts:
2 left
💡 Hint

Think about what the middleware does when the token is missing.

📝 Syntax
intermediate
2:00remaining
Identify the syntax error in this Next.js middleware code

Which option contains the correct syntax for accessing cookies in Next.js middleware?

NextJS
export function middleware(request) {
  const token = request.cookies.get('token')?.value;
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}
Aconst token = request.cookies.get('token')?.value;
Bconst token = request.cookies['token'];
Cconst token = request.cookies.get('token');
Dconst token = request.cookies.token.value;
Attempts:
2 left
💡 Hint

Check the official Next.js middleware API for cookie access.

state_output
advanced
2:00remaining
What is the output when middleware allows access with a valid token?

Given this middleware, what will the user see when accessing /dashboard/settings with a valid token cookie?

NextJS
import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('token')?.value;
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: '/dashboard/:path*',
};

// Assume /dashboard/settings page returns <h1>Settings Page</h1>
AThe user is redirected to /login.
BThe user sees the <h1>Settings Page</h1> content.
CThe user sees a blank page with no content.
DThe middleware throws an error and the page does not load.
Attempts:
2 left
💡 Hint

What does NextResponse.next() do?

🔧 Debug
advanced
2:00remaining
Why does this middleware fail to protect the route?

Review this middleware code. Why does it fail to redirect unauthenticated users?

NextJS
import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('token');
  if (!token) {
    NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: '/dashboard/:path*',
};
AThe matcher pattern does not match the route correctly.
BThe cookie access syntax is incorrect and throws an error.
CNextResponse.next() should be called before the redirect.
DThe redirect response is not returned, so the middleware continues and allows access.
Attempts:
2 left
💡 Hint

Check if the redirect response is properly handled.

🧠 Conceptual
expert
3:00remaining
How does Next.js middleware improve protected route performance?

Which statement best explains how Next.js middleware enhances the performance of protected routes compared to client-side checks?

AMiddleware caches protected pages on the client to speed up future loads.
BMiddleware delays page rendering until client-side JavaScript verifies authentication.
CMiddleware runs on the edge before the page loads, preventing unauthorized requests early and reducing client load.
DMiddleware duplicates authentication logic on both server and client, increasing security checks.
Attempts:
2 left
💡 Hint

Think about where middleware runs in the request lifecycle.

Practice

(1/5)
1. What is the main purpose of middleware in Next.js when protecting routes?
easy
A. To check user authentication before allowing access to certain pages
B. To style the pages dynamically based on user preferences
C. To preload images for faster page loading
D. To manage database connections automatically

Solution

  1. Step 1: Understand middleware role

    Middleware runs before a page loads to control access or modify requests.
  2. Step 2: Identify protection purpose

    In protected routes, middleware checks if a user is authenticated before allowing access.
  3. Final Answer:

    To check user authentication before allowing access to certain pages -> Option A
  4. Quick Check:

    Middleware protects routes by checking authentication [OK]
Hint: Middleware runs before page load to check user access [OK]
Common Mistakes:
  • Thinking middleware styles pages
  • Confusing middleware with database management
  • Assuming middleware preloads images
2. Which of the following is the correct way to export middleware in Next.js to protect routes?
easy
A. export function middleware() { /* code */ }
B. function middleware() { /* code */ } export middleware
C. export middleware = () => { /* code */ }
D. export default function middleware(req) { /* code */ }

Solution

  1. Step 1: Recall Next.js middleware export syntax

    Middleware must be exported as the default export function named middleware.
  2. Step 2: Check options for correct syntax

    Only export default function middleware(req) { /* code */ } uses "export default function middleware(req)" which is valid syntax.
  3. Final Answer:

    export default function middleware(req) { /* code */ } -> Option D
  4. Quick Check:

    Middleware uses default export function [OK]
Hint: Middleware must be default exported as a function named middleware [OK]
Common Mistakes:
  • Using named export instead of default
  • Assigning middleware to a variable without export default
  • Incorrect export statement syntax
3. Given this middleware code snippet, what happens when a user is not authenticated?
import { NextResponse } from 'next/server';

export default function middleware(req) {
  const token = req.cookies.get('token');
  if (!token) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  return NextResponse.next();
}
medium
A. The user stays on the current page without any change
B. The user is redirected to the /login page
C. The middleware throws an error and stops loading
D. The user is redirected to the homepage

Solution

  1. Step 1: Analyze token check in middleware

    The middleware checks if the 'token' cookie exists; if not, it triggers a redirect.
  2. Step 2: Understand redirect behavior

    If no token, middleware returns a redirect response to '/login' page.
  3. Final Answer:

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

    No token causes redirect to login [OK]
Hint: No token cookie means redirect to login page [OK]
Common Mistakes:
  • Assuming user stays on page without token
  • Thinking middleware throws error on missing token
  • Confusing redirect target URL
4. Identify the error in this middleware code that aims to protect routes:
import { NextResponse } from 'next/server';

export default function middleware(req) {
  const token = req.cookies.token;
  if (!token) {
    return NextResponse.redirect('/login');
  }
  return NextResponse.next();
}
medium
A. Missing async keyword in middleware function
B. Redirect URL should be absolute, not relative
C. Accessing cookies incorrectly; should use req.cookies.get('token')
D. NextResponse.next() should be replaced with NextResponse.continue()

Solution

  1. Step 1: Check cookie access method

    In Next.js middleware, cookies are accessed with req.cookies.get('token'), not req.cookies.token.
  2. Step 2: Verify redirect usage

    Redirect can accept a relative path, so that is valid here.
  3. Final Answer:

    Accessing cookies incorrectly; should use req.cookies.get('token') -> Option C
  4. Quick Check:

    Use req.cookies.get('token') to read cookies [OK]
Hint: Use req.cookies.get('token') to read cookies in middleware [OK]
Common Mistakes:
  • Using dot notation for cookies object
  • Thinking redirect URL must be absolute
  • Confusing NextResponse.next() with continue()
5. You want to protect only the routes starting with /dashboard using middleware. Which is the correct way to apply middleware only to these routes?
hard
A. export const config = { matcher: ['/dashboard/:path*'] };
B. export const config = { matcher: ['/dashboard*'] };
C. export const config = { matcher: ['/dashboard'] };
D. export const config = { matcher: ['/dashboard/**'] };

Solution

  1. Step 1: Understand matcher pattern syntax

    The matcher uses path patterns where ':path*' matches all subpaths under /dashboard.
  2. Step 2: Compare options for correct pattern

    export const config = { matcher: ['/dashboard/:path*'] }; uses '/dashboard/:path*' which correctly matches /dashboard and all nested routes.
  3. Final Answer:

    export const config = { matcher: ['/dashboard/:path*'] }; -> Option A
  4. Quick Check:

    Use '/dashboard/:path*' to match dashboard and subpaths [OK]
Hint: Use ':path*' to match all subpaths under a route [OK]
Common Mistakes:
  • Using wildcard * without colon for subpaths
  • Matching only exact /dashboard without subpaths
  • Using invalid glob pattern like /**