Skip to the solution
MediumFrontend9 min read

How do you debug Server Functions and hydration mismatches in Next.js 16.2?

284 views

The problem

Question presented to candidate: "A user reports that 'Add to cart' sometimes fails, and our error tracker also shows a hydration error on the product page. Using what Next.js 16.2 added for debugging, how do you find out which Server Function was called with what, why it failed, and exactly which text did not match during hydration?"

What a strong answer should cover:

  • Server Function logging (16.2): next dev prints each call under its request with the function name, arguments, duration and file, on by default and controlled by logging.serverFunctions.
  • Browser-to-terminal forwarding: logging.browserToTerminal (moved out of experimental in 16.2) sends browser warnings and errors to the dev terminal by default, all output with true.
  • Hydration errors show a server/client diff (+ client, - server) in the overlay and terminal; common causes are typeof window branches, Date.now(), locale formatting and invalid nesting.
  • Fixes: render the same output on both sides, move client-only values into useEffect or a client-only component, use suppressHydrationWarning only for a single unavoidable text node.
  • Production: messages are hidden from the browser (a digest), so correlate with server logs; next start --inspect (16.2) attaches a debugger to the production server.

Clarifying questions expected:

  • "Does it reproduce in next dev?" β€” the rich logs and diffs are development features.
  • "Is the failure on the server or in the browser?" β€” the terminal shows both now.

Code / implementation expected: Optional β€” the logging config and a fixed hydration-safe component.

  • nextjs
  • debugging
  • hydration
  • server-functions
  • next-16

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

9 min read Β· 8 sections

Read the code

next.config.ts: dev logging options
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  logging: {
    serverFunctions: true, // default in dev: one line per Server Function call
    browserToTerminal: true, // default 'warn'; true forwards console.log too
    fetches: { fullUrl: true },
    incomingRequests: { ignore: [/\/api\/health/] },
  },
};

export default nextConfig;
A hydration-safe version of the lab component
"use client";
import { useEffect, useState } from "react";

// Same output on the server and in the first client render, then switch after mount
export function WhereAmI() {
  const [where, setWhere] = useState("server");
  useEffect(() => setWhere("client"), []);
  return <p id="where">rendered on the {where}</p>;
}
The lab Client Component that calls the Server Function
"use client";
import { useState } from "react";
import { addItem } from "./actions";

export default function Cart() {
  const [msg, setMsg] = useState("");
  return (
    <main>
      <button id="add" onClick={async () => {
        console.log("add clicked");
        console.warn("slow network?");
        const r = await addItem("apple", 3);
        setMsg(`added ${r.qty} ${r.name}`);
      }}>add</button>
      <button id="fail" onClick={async () => {
        try { await addItem("pear", 99); } catch (e) { console.error("action failed:", (e as Error).message); }
      }}>fail</button>
      <p id="msg">{msg}</p>
    </main>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 81 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

How do you keep secrets and server code out of the client bundle in Next.js (server-only, taint, Data Access Layer)?

Continue