On this page

Tutorial8 min read

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

Next.js has two separate debugging environments — server and client. Here's how to attach VS Code to both simultaneously, debug Server Components, API routes, hydration errors, and middleware with breakpoints that actually work.

nextjsvscodedebuggingreactserver-componentsapi-routes

Understanding the Two Environments

Next.js debugging is split across two environments: the server (Node.js process running your Server Components and API routes) and the client (browser running your Client Components). VS Code can attach to both simultaneously.

EnvironmentWhat runs hereHow to debug
ServerServer Components, API routes, middleware, getServerSidePropsVS Code Node.js debugger
ClientClient Components ('use client'), browser events, stateBrowser DevTools + VS Code Chrome debugger

Errors in Server Components appear in the terminal. Errors in Client Components appear in the browser console. Knowing which side you're on determines which tool to open.

Step 1: Configure VS Code for Next.js

Create .vscode/launch.json:

json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000"
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/next",
      "args": ["dev"],
      "env": {
        "NODE_OPTIONS": "--inspect"
      },
      "serverReadyAction": {
        "action": "debugWithChrome",
        "killOnServerStop": true,
        "pattern": "started server on .+, url: (https?://.+)",
        "uriFormat": "%s",
        "webRoot": "${workspaceFolder}"
      }
    }
  ]
}

Use "Next.js: debug full stack" to attach VS Code to both server and browser simultaneously. Set breakpoints in Server Components and Client Components — both pause in VS Code.

Step 2: Debug Server Components

Server Components run on the Node.js server. Errors appear in the terminal where npm run dev is running.

typescript
// app/dashboard/page.tsx — Server Component (default in App Router)
export default async function DashboardPage() {
  const data = await fetchUserData()  // ← if this throws, error is in terminal
  return <Dashboard data={data} />
}

Set a breakpoint on the fetchUserData() line. When the page loads, VS Code pauses and you can inspect data before it reaches the component.

Note: Server Components run on each request — breakpoints trigger every time the page is visited. Use conditional breakpoints (right-click → Edit Breakpoint → add condition) to prevent pausing on every load.

Step 3: Debug Client Components

Client Components ('use client') run in the browser. Use browser DevTools or VS Code Chrome debugger.

typescript
'use client'

export function SearchBar() {
  const [query, setQuery] = useState('')

  const handleSearch = () => {
    // Breakpoint here → VS Code pauses when user clicks search
    fetchResults(query).then(setResults)
  }
}

With "Next.js: debug full stack" running, breakpoints in Client Components pause in VS Code — not in the browser. Source maps translate browser execution back to your TypeScript source.

Tip: If VS Code breakpoints in Client Components don't bind, check that sourceMapPathOverrides in your launch config maps webpack paths to your source. The default Next.js config usually works without extra setup.

Step 4: Debug API Routes

API routes (in app/api/ or pages/api/) run on the server. Same debugger as Server Components.

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

Test API routes with curl while the debugger is attached:

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

VS Code pauses at the breakpoint, you inspect body, step through createUser, see the return value.

Step 5: Fix Hydration Errors

The most common Next.js error:

Error: Hydration failed because the initial UI does not match what was rendered on the server.

Hydration mismatch happens when server-rendered HTML doesn't match what React renders on the client. Common causes:

Cause: browser-only API used in a component that renders on both sides

typescript
// ❌ window is undefined on server — renders differently
function Sidebar() {
  return <div>{window.innerWidth > 768 ? 'Desktop' : 'Mobile'}</div>
}

Fix: Gate browser-only code with useEffect (runs client-side only).

typescript
// ✅ Only renders after hydration, not during SSR
'use client'

function Sidebar() {
  const [isMobile, setIsMobile] = useState(false)

  useEffect(() => {
    setIsMobile(window.innerWidth <= 768)
  }, [])

  return <div>{isMobile ? 'Mobile' : 'Desktop'}</div>
}

Cause: date or random value rendered differently on server vs client

typescript
// ❌ Different value on server and client
<p>Generated: {new Date().toLocaleString()}</p>

Fix: Move dynamic values into state initialized in useEffect.

typescript
'use client'

function Timestamp() {
  const [time, setTime] = useState('')
  useEffect(() => setTime(new Date().toLocaleString()), [])
  return <p>Generated: {time}</p>
}

Step 6: Debug Middleware

Next.js middleware runs at the edge before the request reaches your route. Errors here are silent by default.

typescript
// middleware.ts
export function middleware(request: NextRequest) {
  const token = request.cookies.get('session')
  console.log('middleware token:', token?.value)

  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
}

Note: Middleware runs in the Edge Runtime, not Node.js. VS Code's Node debugger can't attach to it. Use console.log for middleware debugging — logs appear in the terminal.

Common Next.js Errors Quick Reference

ErrorEnvironmentCause
Hydration failedClientServer/client render mismatch
window is not definedServerBrowser API in Server Component
useEffect not availableServerClient hook in Server Component — add 'use client'
404 on dynamic routeServergenerateStaticParams returned empty or dynamicParams = false
Middleware redirect loopEdgeRedirect target also matches middleware — add exclusion
CORS on API routeServerAPI route missing headers — add Access-Control-Allow-Origin response header

For Next.js errors that span Server Components, Client Components, and API routes — especially data-fetching bugs where the wrong data arrives at the wrong component — paste the component tree and the error into DebugAI. It reads the full chain from server fetch to client render and identifies where data goes wrong.

Debug faster starting today.

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

Install Free →

Related Posts

Tutorial

How to Debug a FastAPI Application (Complete VS Code Guide)

9 min read

Tutorial

Fix KeyError in Python: 5 Causes and How to Find the Source

5 min read

← All posts