Dev.to WebDev 🛠 Dev 👁 0 📖 1 min read

Next.js 15 is a one-line upgrade. The breaking changes are in every file that reads a cookie.

Upgrading to Next.js 15 is one line: - "next": "14.2.15" + "next": "15.0.3" The work is in the files that line affects. Three changes cause most of it. 1. Request APIs are async cookies(), headers()

Upgrading to Next.js 15 is one line:

- "next": "14.2.15"
+ "next": "15.0.3"

The work is in the files that line affects. Three changes cause most of it.

1. Request APIs are async

cookies(), headers() and draftMode() now return promises.

  import { cookies } from "next/headers";

  export default async function Page() {
-   const theme = cookies().get("theme");
+   const theme = (await cookies()).get("theme");
    ...
  }

Next.js keeps a temporary synchronous fallback that logs a warning, which is kind for the upgrade and unkind for finding the problem: the code keeps working, and the warning sits in your logs.

In route params, the same applies: params and searchParams in pages and layouts are promises too.

2. fetch() isn't cached by default

In 14, fetch() in a server component was cached unless you opted out. In 15 it isn't cached unless you opt in:

await fetch(url, { cache: "force-cache" });

Nothing breaks. Some pages that were fast because of a cache you never meant to rely on get slower.

3. GET route handlers aren't cached

Same idea for app/**/route.ts: a GET handler is dynamic by default now. Add export const dynamic = "force-static" where you really wanted it cached.

Finding every affected file

The official codemod handles most of change 1:

npx @next/codemod@canary upgrade latest

Then search for what's left, because codemods miss dynamic patterns and helper functions:

grep -rnE "cookies\(\)|headers\(\)|draftMode\(\)" app src
grep -rn "fetch(" app src | grep -v "cache:"

And run your build and tests before you call it done. next build catches type errors from the async change if your project is typed.

This "the release notes say what changed, but not where it hits your code" step is the part Versyka automates: it reads the release notes against your repository, rewrites the affected calls and runs your checks before and after.

Have you moved to Next.js 15 yet? What broke first?

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.