{
  "id": "migrate-nextjs-14-to-16",
  "type": "playbooks",
  "category": "playbooks",
  "locale": "de",
  "url": "/de/playbooks/migrate-nextjs-14-to-16",
  "title": "Prompt-to-PR: Next.js 14 auf 16 migrieren",
  "description": "Schritt-für-Schritt-SOP zur Migration eines Next.js 14 App Router-Projekts auf Next.js 16 — Turbopack, React 19, asynchrone APIs und Caching-Änderungen abgedeckt.",
  "tools": [
    "Cursor",
    "Claude Code",
    "Codex",
    "Windsurf"
  ],
  "stack": [
    "Next.js",
    "TypeScript"
  ],
  "tags": [
    "nextjs",
    "typescript",
    "migrate"
  ],
  "difficulty": "hard",
  "updated": "2026-06-08",
  "markdown": "Next.js 16 bringt React 19, asynchrone `params` und `searchParams`, überarbeitetes Fetch-Caching und Turbopack als Standard-Dev-Bundler. Dieses Playbook hält den Agenten auf die Breaking Changes fokussiert und verhindert, dass er funktionierenden Code umschreibt.\n\n## 1. Anforderung\n\nAktualisieren Sie `next` von 14.x auf 16.x (und `react`/`react-dom` auf 19.x) ohne Funktionsrückschritte. Behandeln Sie jeden Breaking Change, der durch den offiziellen Codemod aufgedeckt wird, sowie alle verbleibenden Probleme, die nicht davon erfasst werden.\n\n## 2. Erster Prompt\n\n```txt title=\"First Prompt\"\nMigrate this project from Next.js 14 to Next.js 16. Follow these steps exactly.\n\nStep 1 — run the official codemod:\n  npx @next/codemod@latest upgrade latest --yes\n\nStep 2 — manual fixes the codemod does not cover:\n  a. `params` and `searchParams` in page.tsx/layout.tsx files are now Promises.\n     Await them: `const { id } = await params;`\n     Do NOT destructure params in the function signature.\n  b. `cookies()`, `headers()`, `draftMode()` are now async.\n     Add `await` before every call.\n  c. `fetch()` is no longer cached by default in Route Handlers.\n     Where caching is intentional, add `{ next: { revalidate: N } }`.\n  d. Remove any `export const dynamic = 'force-dynamic'` that is now the default.\n  e. Replace `<Image>` with the new `onLoad` prop signature if present.\n\nStep 3 — update package.json:\n  \"next\": \"^16.0.0\"\n  \"react\": \"^19.0.0\"\n  \"react-dom\": \"^19.0.0\"\n  \"@types/react\": \"^19.0.0\"\n  \"@types/react-dom\": \"^19.0.0\"\n\nDo not change any business logic, UI, or database code.\nList every file you changed and why.\n```\n\n## 3. Erwartete Dateiänderungen\n\n```txt\npackage.json                          (next, react, react-dom, @types/react*)\nsrc/app/**/page.tsx                   (await params / searchParams)\nsrc/app/**/layout.tsx                 (await params where used)\nsrc/app/api/**/route.ts               (await cookies/headers; fetch cache opts)\nsrc/middleware.ts                     (if it uses deprecated config keys)\nnext.config.ts                        (remove deprecated options)\n```\n\n## 4. Überprüfungsliste\n\n- `package.json` setzt `next` auf `^16.0.0` und React auf `^19.0.0`.\n- Jede Seite/jedes Layout, das `params` destrukturiert, wartet jetzt zuerst darauf.\n- Keine synchronen `cookies()`- oder `headers()`-Aufrufe verbleiben in Serverkomponenten.\n- `fetch`-Aufrufe, die zuvor auf implizites Caching angewiesen waren, haben jetzt eine explizite `revalidate`- oder `no-store`-Option.\n- `next.config.ts` enthält keine veralteten Schlüssel `experimental.appDir` oder `swcMinify`.\n- TypeScript kompiliert mit `bun tsc --noEmit` — null Fehler.\n- Der Agent hat keine UI-Komponenten oder Geschäftslogik umgeschrieben.\n\n## 5. Testbefehle\n\n```bash\n# Install updated deps\nbun install\n\n# Type-check\nbun tsc --noEmit\n\n# Dev build (Turbopack default in Next.js 16)\nbun dev\n\n# Production build — catches async-params errors at compile time\nbun run build\n\n# Run existing test suite\nbun test\n```\n\n## 6. Häufige Fehler\n\n- **`params.id` vor await verwendet** — TypeScript-Fehler: `Property 'id' does not exist on type 'Promise<...>'`. Der Agent wartet manchmal in einer Datei auf `params`, in einer anderen nicht.\n- **`cookies()` nicht awaited** — Laufzeitfehler: `cookies() was called outside of a Server Component`. Fügen Sie `await` hinzu.\n- **Turbopack inkompatibles webpack-Plugin** — `next dev` meldet Fehler bei einer benutzerdefinierten `webpack()`-Konfiguration. Turbopack ignoriert webpack-Plugins; migrieren Sie sie oder schalten Sie sie bedingt aus.\n- **`@types/react`-Versionskonflikt** — Peer-Abhängigkeitskonflikt zwischen alten Komponentenbibliotheken und React 19-Typen. Fixieren Sie `@types/react` auf 19 und überschreiben Sie ggf.\n- **`useFormState` entfernt** — ersetzt durch `useActionState` aus `react`. Der Codemod fängt dies normalerweise ab, aber bestätigen Sie.\n\n## 7. Fehlerbehebung-Prompt\n\n```txt title=\"Fix Prompt\"\nTypeScript reports: \"Property 'slug' does not exist on type\n'Promise<{ slug: string }>'\" in src/app/blog/[slug]/page.tsx.\n\nThe page function signature must be:\n  export default async function Page({ params }: { params: Promise<{ slug: string }> })\n\nThen at the top of the function body:\n  const { slug } = await params;\n\nApply the same fix to every other page or layout that destructures params\nwithout awaiting. List every file changed.\n```\n\n## 8. PR-Beschreibung\n\n```md title=\"PR description\"\n## Chore: Migrate Next.js 14 → 16 + React 19\n\n**Breaking changes addressed**:\n- `params` / `searchParams` are now `Promise`s — awaited in all pages/layouts\n- `cookies()` / `headers()` are now async — awaited in all Server Components\n- Fetch caching defaults changed — explicit `revalidate` added where needed\n- Removed deprecated `next.config.ts` keys (`swcMinify`, `experimental.appDir`)\n\n**Tooling**: dev server now uses Turbopack by default (`next dev --turbopack`).\n\nRun `bun run build` to confirm zero type errors before merging.\n```"
}