On this page

Engineering8 min read

How to Debug a Next.js Application in VS Code (App Router Guide)

Complete guide to debugging Next.js 14+ with the App Router: server components, client components, API routes, and build errors, using VS Code and AI tools.

Next.jsdebuggingVS CodeReactApp Router

Next.js Debugging Is Split in Two

Next.js runs code in two places: the server (Node.js, for Server Components and API routes) and the browser (for Client Components). Errors in each place look different, surface differently, and require different debugging approaches.

Before you debug anything, identify which side the error is on:

  • Error in the terminal where you ran next dev: server-side
  • Error in browser DevTools console: client-side
  • Error during next build: build-time, TypeScript, import errors, static generation

This guide covers all three.

Debugging Server-Side Errors

Server Components run on the Node.js server. Their errors print to the terminal, not the browser.

Error: Error: ENOENT: no such file or directory, open '/app/.env.local'

This appears in the terminal only. The browser shows a generic "An error occurred" page in production, or a red error overlay in dev mode.

Read the Terminal Stack Trace

Next.js dev mode prints the full stack trace for server errors:

Error: Cannot read properties of undefined (reading 'id')
    at UserDashboard (./src/app/dashboard/page.jsx:23:18)
    at async Page (./src/app/dashboard/page.jsx:10:3)

Start from the bottom of the trace, find your code, ignore Next.js internals, and go to that line.

Set Up VS Code Debugger for Next.js

Create .vscode/launch.json:

json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev"
    }
  ]
}

Start debugging with F5. Set breakpoints in any Server Component, layout.jsx, or route.ts file. When a page request hits, the debugger pauses and you can inspect server-side variables, auth state, and database query results directly.

Note: In Next.js 14+ App Router, breakpoints work in both Server Components and Route Handlers. Client Components need the browser DevTools debugger, not the VS Code debugger.

Debugging Client-Side Errors

Client Components render in the browser. Their errors show in DevTools under the Console tab.

The React Error Overlay

In dev mode, unhandled Client Component errors show a red overlay with the component stack:

TypeError: Cannot read properties of null (reading 'user')

The above error occurred in the <ProfileCard> component:
    at ProfileCard (src/components/ProfileCard.jsx:12)
    at div
    at UserDashboard (src/app/dashboard/page.jsx:18)

Read the component stack bottom-up to find which component caused the error and which parent rendered it.

Use Chrome DevTools Sources Panel

For complex client-side bugs:

  1. Open DevTools and go to the Sources tab
  2. Press Ctrl+P and type the component filename
  3. Click a line number to set a breakpoint
  4. Trigger the action that causes the error
  5. Execution pauses so you can inspect variable state in the right panel

Tip: Next.js dev mode generates source maps automatically. You can debug your original .jsx and .tsx files in DevTools, not the compiled output. Line numbers and variable names match your actual code.

Common Client-Side Errors

Hydration failed because the server rendered HTML did not match the client.

Cause: the component renders differently on server vs client. Usually new Date(), Math.random(), or window access during render. Move the call to useEffect. Full guide: How to Fix the Next.js Hydration Error.

useState can only be used in a Client Component. Add the "use client" directive at the top of the file.

Fix: Add 'use client' as the very first line of the component file, above all imports.

Debugging API Routes

API routes in app/api/*/route.ts run server-side. Errors print to the terminal.

typescript
// app/api/users/route.ts
export async function POST(request: Request) {
  const body = await request.json()
  // Set breakpoint here to inspect body
  const user = await createUser(body)
  return Response.json(user)
}

Test API routes with curl:

bash
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "email": "alice@example.com"}'

Tip: Install the REST Client VS Code extension. Create a .http file in your project to save test requests alongside your code. Faster than Postman for rapid iteration.

Debugging Build Errors

next build errors stop deployment. Three main categories.

TypeScript Errors

Type error: Type 'string | null' is not assignable to type 'string'.

Run npx tsc --noEmit locally before pushing. It catches all TypeScript errors without doing a full build and gives faster feedback.

Missing Environment Variables

Next.js fails the build if a NEXT_PUBLIC_* variable referenced in code is not set:

Error: ReferenceError: NEXT_PUBLIC_API_URL is not defined

Fix: Add the variable to your deployment environment (Vercel dashboard, Settings, Environment Variables) and to your local .env.local. Never hardcode URLs.

Static Generation Failures

Server Components that fail during next build cause build errors with a long trace:

Error occurred prerendering page "/blog/[slug]"
...
Error: fetch failed

This means your page called a fetch that failed at build time. Use next: { revalidate: 3600 } instead of cache: 'no-store' so Next.js generates the page once and caches it rather than fetching at every build.

The Debugging Workflow in Order

When a Next.js error occurs, check these in order:

  1. Terminal: server error? Full stack trace here.
  2. Browser console: client error? Component stack here.
  3. Home route vs specific route: does the homepage work? If yes, the bug is route-specific.
  4. Network tab: API route returning wrong status? Check request and response here.
  5. next build locally: build error before deploying? Run the build and read the output.

Note: Do not deploy to test a bug. Reproduce it in next dev first. Build errors that only appear on Vercel are almost always environment variable mismatches between your local .env.local and your deployment config.

Cross-File Errors in App Router

App Router introduces complex dependency chains: layout, page, server component, service, database. An error deep in a database query can surface with a misleading stack trace pointing to the layout.

For these errors, DebugAI reads your full component tree including the page, its layout, the server actions it calls, and the service functions those actions use, then identifies the root cause without you having to follow the chain manually.

Tip: The most time-consuming Next.js bugs are auth errors that appear as 404s or blank pages due to middleware redirecting silently, and data-fetching bugs where null propagates from a database query through 3 layers before causing an error. Both are fast to solve with codebase-aware analysis.

Quick Reference

Error typeWhere it appearsTool to use
Server Component runtime errorTerminalVS Code debugger + terminal trace
Client Component runtime errorBrowser consoleChrome DevTools + error overlay
Hydration mismatchBrowser consoleCheck server vs client render diff
API route errorTerminal + network tabcurl test + terminal trace
Build errornext build outputFix TypeScript and env vars first
Auth or middleware redirect bugNo error, blank pageCheck middleware.ts conditions

For cross-file App Router errors where null propagates through layouts and server actions before crashing, paste the component tree into DebugAI. It traces the full chain and identifies the root cause directly.

Debug faster starting today.

Free VS Code extension. 10 sessions/day. No credit card.

Install Free →

Related Posts

Engineering

GitHub Copilot Just Changed Its Pricing. What Developers Need to Know

5 min read

Engineering

Why Your AI Agent Harness Fails at Debugging (And How to Fix It)

5 min read

← All posts