@nx/next 22.1.2 → 22.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/migrations.json CHANGED
@@ -5,6 +5,15 @@
5
5
  "version": "22.0.0-beta.0",
6
6
  "description": "Updates next.config.js files to add SVGR webpack configuration directly instead of using the nx.svgr option in withNx.",
7
7
  "factory": "./src/migrations/update-22-0-0/add-svgr-to-next-config"
8
+ },
9
+ "update-22-2-0-create-ai-instructions-for-next-16": {
10
+ "cli": "nx",
11
+ "version": "22.2.0-beta.1",
12
+ "requires": {
13
+ "next": ">=16.0.0"
14
+ },
15
+ "description": "Create AI Instructions to help migrate users workspaces to Next.js 16.",
16
+ "factory": "./src/migrations/update-22-2-0/create-ai-instructions-for-next-16"
8
17
  }
9
18
  },
10
19
  "packageJsonUpdates": {
@@ -40,6 +49,22 @@
40
49
  "alwaysAddToPackageJson": false
41
50
  }
42
51
  }
52
+ },
53
+ "22.2.0-beta.1": {
54
+ "version": "22.2.0-beta.1",
55
+ "requires": {
56
+ "next": "^15.0.0"
57
+ },
58
+ "packages": {
59
+ "next": {
60
+ "version": "~16.0.1",
61
+ "alwaysAddToPackageJson": false
62
+ },
63
+ "eslint-config-next": {
64
+ "version": "^16.0.1",
65
+ "alwaysAddToPackageJson": false
66
+ }
67
+ }
43
68
  }
44
69
  }
45
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/next",
3
- "version": "22.1.2",
3
+ "version": "22.2.0-beta.1",
4
4
  "private": false,
5
5
  "description": "The Next.js plugin for Nx contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides:\n\n\n- Scaffolding for creating, building, serving, linting, and testing Next.js applications.\n\n- Integration with building, serving, and exporting a Next.js application.\n\n- Integration with React libraries within the workspace. \n\nWhen using Next.js in Nx, you get the out-of-the-box support for TypeScript, Playwright, Cypress, and Jest. No need to configure anything: watch mode, source maps, and typings just work.",
6
6
  "repository": {
@@ -35,7 +35,7 @@
35
35
  "next": ">=14.0.0 <17.0.0"
36
36
  },
37
37
  "dependencies": {
38
- "@nx/devkit": "22.1.2",
38
+ "@nx/devkit": "22.2.0-beta.1",
39
39
  "@babel/plugin-proposal-decorators": "^7.22.7",
40
40
  "@svgr/webpack": "^8.1.0",
41
41
  "copy-webpack-plugin": "^10.2.4",
@@ -44,17 +44,17 @@
44
44
  "semver": "^7.6.3",
45
45
  "tslib": "^2.3.0",
46
46
  "webpack-merge": "^5.8.0",
47
- "@nx/js": "22.1.2",
48
- "@nx/eslint": "22.1.2",
49
- "@nx/react": "22.1.2",
50
- "@nx/web": "22.1.2",
51
- "@nx/webpack": "22.1.2",
47
+ "@nx/js": "22.2.0-beta.1",
48
+ "@nx/eslint": "22.2.0-beta.1",
49
+ "@nx/react": "22.2.0-beta.1",
50
+ "@nx/web": "22.2.0-beta.1",
51
+ "@nx/webpack": "22.2.0-beta.1",
52
52
  "@phenomnomnominal/tsquery": "~5.0.1"
53
53
  },
54
54
  "devDependencies": {
55
- "@nx/cypress": "22.1.2",
56
- "@nx/playwright": "22.1.2",
57
- "nx": "22.1.2"
55
+ "@nx/cypress": "22.2.0-beta.1",
56
+ "@nx/playwright": "22.2.0-beta.1",
57
+ "nx": "22.2.0-beta.1"
58
58
  },
59
59
  "publishConfig": {
60
60
  "access": "public"
@@ -0,0 +1,3 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export default function createAiInstructionsForNext16(tree: Tree): Promise<string[]>;
3
+ //# sourceMappingURL=create-ai-instructions-for-next-16.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ai-instructions-for-next-16.d.ts","sourceRoot":"","sources":["../../../../../../packages/next/src/migrations/update-22-2-0/create-ai-instructions-for-next-16.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,wBAA8B,6BAA6B,CAAC,IAAI,EAAE,IAAI,qBAerE"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = createAiInstructionsForNext16;
4
+ const path_1 = require("path");
5
+ const fs_1 = require("fs");
6
+ async function createAiInstructionsForNext16(tree) {
7
+ const pathToAiInstructions = (0, path_1.join)(__dirname, 'files', 'ai-instructions-for-next-16.md');
8
+ if (!(0, fs_1.existsSync)(pathToAiInstructions)) {
9
+ return;
10
+ }
11
+ const contents = (0, fs_1.readFileSync)(pathToAiInstructions, 'utf-8');
12
+ tree.write('ai-migrations/MIGRATE_NEXT_16.md', contents);
13
+ return [
14
+ `We created 'ai-migrations/MIGRATE_NEXT_16.md' with instructions for an AI Agent to help migrate your Next.js projects to Next.js 16.`,
15
+ ];
16
+ }
@@ -0,0 +1,845 @@
1
+ # Next.js 16 Migration Instructions for LLM
2
+
3
+ ## Overview
4
+
5
+ These instructions guide you through migrating an Nx workspace containing Next.js projects from Next.js 15 to Next.js 16. Work systematically through each breaking change category.
6
+
7
+ ## Pre-Migration Checklist
8
+
9
+ 1. **Identify all Next.js projects**:
10
+
11
+ ```bash
12
+ nx show projects --with-target build | xargs -I {} nx show project {} --json | jq -r 'select(.targets.build.executor | contains("next")) | .name'
13
+ ```
14
+
15
+ Or search for Next.js configuration files:
16
+
17
+ ```bash
18
+ find . -name "next.config.*" -not -path "*/node_modules/*"
19
+ ```
20
+
21
+ 2. **Update packages**:
22
+
23
+ ```bash
24
+ npm install next@latest react@latest react-dom@latest
25
+ npm install -D @types/react @types/react-dom # if using TypeScript
26
+ ```
27
+
28
+ 3. **Verify minimum requirements**:
29
+ - Node.js 20.9+ (Node.js 18 is no longer supported)
30
+ - TypeScript 5.1.0+
31
+ - Browser support: Chrome 111+, Edge 111+, Firefox 111+, Safari 16.4+
32
+
33
+ ## Migration Steps by Category
34
+
35
+ ### 1. Async Request APIs (Major Breaking Change)
36
+
37
+ This is the most impactful change in Next.js 16. All dynamic request APIs are now asynchronous.
38
+
39
+ **Search Patterns**:
40
+
41
+ - `cookies()` usage in server components
42
+ - `headers()` usage in server components
43
+ - `draftMode()` usage
44
+ - `params` in page, layout, route handlers, and metadata files
45
+ - `searchParams` in page components
46
+
47
+ #### 1.1 Page Components with params
48
+
49
+ **Changes Required**:
50
+
51
+ ```tsx
52
+ // BEFORE (Next.js 15)
53
+ export default function Page({ params }) {
54
+ const { slug } = params;
55
+ return <h1>{slug}</h1>;
56
+ }
57
+
58
+ // AFTER (Next.js 16)
59
+ export default async function Page(props) {
60
+ const { slug } = await props.params;
61
+ return <h1>{slug}</h1>;
62
+ }
63
+ ```
64
+
65
+ **Action Items**:
66
+
67
+ - [ ] Make all page components that use `params` async
68
+ - [ ] Add `await` before accessing `props.params`
69
+ - [ ] Update TypeScript types if applicable
70
+
71
+ #### 1.2 Page Components with searchParams
72
+
73
+ **Changes Required**:
74
+
75
+ ```tsx
76
+ // BEFORE (Next.js 15)
77
+ export default function Page({ searchParams }) {
78
+ const query = searchParams.q;
79
+ return <Results query={query} />;
80
+ }
81
+
82
+ // AFTER (Next.js 16)
83
+ export default async function Page(props) {
84
+ const searchParams = await props.searchParams;
85
+ const query = searchParams.q;
86
+ return <Results query={query} />;
87
+ }
88
+ ```
89
+
90
+ **Action Items**:
91
+
92
+ - [ ] Make all page components that use `searchParams` async
93
+ - [ ] Add `await` before accessing `props.searchParams`
94
+
95
+ #### 1.3 Layout Components with params
96
+
97
+ **Changes Required**:
98
+
99
+ ```tsx
100
+ // BEFORE (Next.js 15)
101
+ export default function Layout({ children, params }) {
102
+ const { locale } = params;
103
+ return <div data-locale={locale}>{children}</div>;
104
+ }
105
+
106
+ // AFTER (Next.js 16)
107
+ export default async function Layout(props) {
108
+ const { locale } = await props.params;
109
+ return <div data-locale={locale}>{props.children}</div>;
110
+ }
111
+ ```
112
+
113
+ #### 1.4 Route Handlers
114
+
115
+ **Changes Required**:
116
+
117
+ ```tsx
118
+ // BEFORE (Next.js 15)
119
+ export async function GET(request, { params }) {
120
+ const { id } = params;
121
+ return Response.json({ id });
122
+ }
123
+
124
+ // AFTER (Next.js 16)
125
+ export async function GET(request, props) {
126
+ const { id } = await props.params;
127
+ return Response.json({ id });
128
+ }
129
+ ```
130
+
131
+ #### 1.5 cookies() and headers()
132
+
133
+ **Changes Required**:
134
+
135
+ ```tsx
136
+ // BEFORE (Next.js 15)
137
+ import { cookies, headers } from 'next/headers';
138
+
139
+ export default function Page() {
140
+ const cookieStore = cookies();
141
+ const headersList = headers();
142
+ const theme = cookieStore.get('theme');
143
+ const userAgent = headersList.get('user-agent');
144
+ return <div>...</div>;
145
+ }
146
+
147
+ // AFTER (Next.js 16)
148
+ import { cookies, headers } from 'next/headers';
149
+
150
+ export default async function Page() {
151
+ const cookieStore = await cookies();
152
+ const headersList = await headers();
153
+ const theme = cookieStore.get('theme');
154
+ const userAgent = headersList.get('user-agent');
155
+ return <div>...</div>;
156
+ }
157
+ ```
158
+
159
+ #### 1.6 draftMode()
160
+
161
+ **Changes Required**:
162
+
163
+ ```tsx
164
+ // BEFORE (Next.js 15)
165
+ import { draftMode } from 'next/headers';
166
+
167
+ export default function Page() {
168
+ const { isEnabled } = draftMode();
169
+ return <div>{isEnabled ? 'Draft' : 'Published'}</div>;
170
+ }
171
+
172
+ // AFTER (Next.js 16)
173
+ import { draftMode } from 'next/headers';
174
+
175
+ export default async function Page() {
176
+ const { isEnabled } = await draftMode();
177
+ return <div>{isEnabled ? 'Draft' : 'Published'}</div>;
178
+ }
179
+ ```
180
+
181
+ #### 1.7 generateMetadata with params
182
+
183
+ **Changes Required**:
184
+
185
+ ```tsx
186
+ // BEFORE (Next.js 15)
187
+ export async function generateMetadata({ params }) {
188
+ const { slug } = params;
189
+ return { title: slug };
190
+ }
191
+
192
+ // AFTER (Next.js 16)
193
+ export async function generateMetadata(props) {
194
+ const { slug } = await props.params;
195
+ return { title: slug };
196
+ }
197
+ ```
198
+
199
+ #### 1.8 Automated Migration
200
+
201
+ Run the Next.js codemod for automated migration:
202
+
203
+ ```bash
204
+ npx @next/codemod@canary upgrade latest
205
+ ```
206
+
207
+ Generate type helpers for safer migrations (Next.js 15.5+):
208
+
209
+ ```bash
210
+ npx next typegen
211
+ ```
212
+
213
+ This generates `PageProps`, `LayoutProps`, and `RouteContext` helpers.
214
+
215
+ ### 2. Image Generation Functions
216
+
217
+ **Search Pattern**: `generateImageMetadata`, `default function Image` in opengraph-image or twitter-image files
218
+
219
+ **Changes Required**:
220
+
221
+ ```tsx
222
+ // BEFORE (Next.js 15)
223
+ export function generateImageMetadata({ params }) {
224
+ const { slug } = params;
225
+ return [{ id: '1' }];
226
+ }
227
+
228
+ export default function Image({ params, id }) {
229
+ const slug = params.slug;
230
+ return new ImageResponse(/* ... */);
231
+ }
232
+
233
+ // AFTER (Next.js 16)
234
+ export async function generateImageMetadata({ params }) {
235
+ const { slug } = await params;
236
+ return [{ id: '1' }];
237
+ }
238
+
239
+ export default async function Image({ params, id }) {
240
+ const { slug } = await params;
241
+ const imageId = await id;
242
+ return new ImageResponse(/* ... */);
243
+ }
244
+ ```
245
+
246
+ **Action Items**:
247
+
248
+ - [ ] Make `generateImageMetadata` functions async
249
+ - [ ] Make Image components async
250
+ - [ ] Add `await` for both `params` and `id` access
251
+
252
+ ### 3. Sitemap Generation
253
+
254
+ **Search Pattern**: `sitemap` functions with `id` parameter
255
+
256
+ **Changes Required**:
257
+
258
+ ```tsx
259
+ // BEFORE (Next.js 15)
260
+ export default async function sitemap({ id }) {
261
+ const start = id * 50000;
262
+ // ...
263
+ }
264
+
265
+ // AFTER (Next.js 16)
266
+ export default async function sitemap({ id }) {
267
+ const resolvedId = await id;
268
+ const start = resolvedId * 50000;
269
+ // ...
270
+ }
271
+ ```
272
+
273
+ ### 4. Turbopack Configuration
274
+
275
+ Turbopack is now the default bundler for development.
276
+
277
+ **Search Pattern**: `--turbo` or `--turbopack` flags in package.json scripts, `turbopack` in next.config
278
+
279
+ #### 4.1 Remove Explicit Turbopack Flags
280
+
281
+ ```json
282
+ // BEFORE (Next.js 15)
283
+ {
284
+ "scripts": {
285
+ "dev": "next dev --turbo"
286
+ }
287
+ }
288
+
289
+ // AFTER (Next.js 16) - Turbopack is default
290
+ {
291
+ "scripts": {
292
+ "dev": "next dev"
293
+ }
294
+ }
295
+ ```
296
+
297
+ #### 4.2 Opt Out to Webpack (if needed)
298
+
299
+ ```json
300
+ {
301
+ "scripts": {
302
+ "build": "next build --webpack"
303
+ }
304
+ }
305
+ ```
306
+
307
+ #### 4.3 Move Turbopack Config Out of Experimental
308
+
309
+ ```ts
310
+ // BEFORE (Next.js 15)
311
+ const nextConfig = {
312
+ experimental: {
313
+ turbopack: {
314
+ /* options */
315
+ },
316
+ },
317
+ };
318
+
319
+ // AFTER (Next.js 16)
320
+ const nextConfig = {
321
+ turbopack: {
322
+ /* options */
323
+ },
324
+ };
325
+ ```
326
+
327
+ #### 4.4 Update Sass Imports (Turbopack Specific)
328
+
329
+ ```scss
330
+ /* BEFORE */
331
+ @import '~bootstrap/dist/css/bootstrap.min.css';
332
+
333
+ /* AFTER - Remove tilde prefix */
334
+ @import 'bootstrap/dist/css/bootstrap.min.css';
335
+ ```
336
+
337
+ **Action Items**:
338
+
339
+ - [ ] Remove `--turbo` and `--turbopack` flags from scripts
340
+ - [ ] Move `turbopack` config from `experimental` to root level
341
+ - [ ] Remove tilde (`~`) prefix from Sass imports
342
+ - [ ] Add `--webpack` flag if Webpack is required
343
+
344
+ ### 5. Middleware to Proxy Rename
345
+
346
+ **Search Pattern**: `middleware.ts` or `middleware.js` files
347
+
348
+ **Changes Required**:
349
+
350
+ ```bash
351
+ # Rename the file
352
+ mv middleware.ts proxy.ts
353
+ ```
354
+
355
+ ```ts
356
+ // BEFORE (middleware.ts)
357
+ export function middleware(request) {
358
+ // ...
359
+ }
360
+
361
+ // AFTER (proxy.ts)
362
+ export function proxy(request) {
363
+ // ...
364
+ }
365
+ ```
366
+
367
+ **Config Updates**:
368
+
369
+ ```js
370
+ // BEFORE
371
+ {
372
+ skipMiddlewareUrlNormalize: true;
373
+ }
374
+
375
+ // AFTER
376
+ {
377
+ skipProxyUrlNormalize: true;
378
+ }
379
+ ```
380
+
381
+ **Important**: The Edge runtime is no longer supported in `proxy`. It now uses Node.js runtime.
382
+
383
+ **Action Items**:
384
+
385
+ - [ ] Rename `middleware.ts/js` to `proxy.ts/js`
386
+ - [ ] Rename exported function from `middleware` to `proxy`
387
+ - [ ] Update config option names
388
+ - [ ] Remove Edge runtime usage from proxy files
389
+
390
+ ### 6. Parallel Routes default.js Requirement
391
+
392
+ **Search Pattern**: Directories starting with `@` in the app folder (parallel route slots)
393
+
394
+ All parallel route slots now require an explicit `default.js` file.
395
+
396
+ **Changes Required**:
397
+
398
+ ```tsx
399
+ // Create app/@modal/default.tsx for each parallel route slot
400
+ import { notFound } from 'next/navigation';
401
+
402
+ export default function Default() {
403
+ notFound(); // or return null
404
+ }
405
+ ```
406
+
407
+ **Action Items**:
408
+
409
+ - [ ] Find all parallel route slots (`app/@*/`)
410
+ - [ ] Create `default.tsx` in each slot that doesn't have one
411
+
412
+ ### 7. Image Optimization Changes
413
+
414
+ #### 7.1 Local Images with Query Strings
415
+
416
+ ```tsx
417
+ // Now requires explicit configuration
418
+ <Image src="/assets/photo?v=1" alt="Photo" width="100" height="100" />
419
+ ```
420
+
421
+ ```js
422
+ // next.config.js
423
+ module.exports = {
424
+ images: {
425
+ localPatterns: [
426
+ {
427
+ pathname: '/assets/**',
428
+ search: '?v=1',
429
+ },
430
+ ],
431
+ },
432
+ };
433
+ ```
434
+
435
+ #### 7.2 Default Value Changes
436
+
437
+ Add these to `next.config.js` if you need the old defaults:
438
+
439
+ ```js
440
+ module.exports = {
441
+ images: {
442
+ // minimumCacheTTL changed from 60 to 14400 seconds
443
+ minimumCacheTTL: 60,
444
+
445
+ // Value 16 removed from default imageSizes
446
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
447
+
448
+ // qualities now defaults to [75] only
449
+ qualities: [50, 75, 100],
450
+
451
+ // Local IP now blocked by default
452
+ dangerouslyAllowLocalIP: true, // only for private networks
453
+
454
+ // Maximum redirects changed from unlimited to 3
455
+ maximumRedirects: 5,
456
+ },
457
+ };
458
+ ```
459
+
460
+ #### 7.3 Deprecated images.domains
461
+
462
+ ```js
463
+ // BEFORE - Remove this
464
+ module.exports = {
465
+ images: {
466
+ domains: ['example.com'],
467
+ },
468
+ };
469
+
470
+ // AFTER - Use remotePatterns instead
471
+ module.exports = {
472
+ images: {
473
+ remotePatterns: [
474
+ {
475
+ protocol: 'https',
476
+ hostname: 'example.com',
477
+ },
478
+ ],
479
+ },
480
+ };
481
+ ```
482
+
483
+ **Action Items**:
484
+
485
+ - [ ] Add `localPatterns` for images with query strings
486
+ - [ ] Migrate `images.domains` to `images.remotePatterns`
487
+ - [ ] Review and update default values if needed
488
+
489
+ ### 8. Caching API Updates
490
+
491
+ #### 8.1 Remove unstable\_ Prefix
492
+
493
+ ```ts
494
+ // BEFORE (Next.js 15)
495
+ import {
496
+ unstable_cacheLife as cacheLife,
497
+ unstable_cacheTag as cacheTag,
498
+ } from 'next/cache';
499
+
500
+ // AFTER (Next.js 16)
501
+ import { cacheLife, cacheTag } from 'next/cache';
502
+ ```
503
+
504
+ #### 8.2 New Cache Functions
505
+
506
+ **revalidateTag with cacheLife profile**:
507
+
508
+ ```ts
509
+ 'use server';
510
+ import { revalidateTag } from 'next/cache';
511
+
512
+ export async function updateArticle(articleId: string) {
513
+ revalidateTag(`article-${articleId}`, 'max');
514
+ }
515
+ ```
516
+
517
+ **updateTag (new)**:
518
+
519
+ ```ts
520
+ 'use server';
521
+ import { updateTag } from 'next/cache';
522
+
523
+ export async function updateUserProfile(userId: string, profile: Profile) {
524
+ await db.users.update(userId, profile);
525
+ updateTag(`user-${userId}`);
526
+ }
527
+ ```
528
+
529
+ **refresh (new)**:
530
+
531
+ ```ts
532
+ 'use server';
533
+ import { refresh } from 'next/cache';
534
+
535
+ export async function markNotificationAsRead(notificationId: string) {
536
+ await db.notifications.markAsRead(notificationId);
537
+ refresh();
538
+ }
539
+ ```
540
+
541
+ **Action Items**:
542
+
543
+ - [ ] Remove `unstable_` prefix from `cacheLife` and `cacheTag` imports
544
+ - [ ] Consider using new `updateTag` and `refresh` functions
545
+
546
+ ### 9. React Compiler Support
547
+
548
+ React Compiler is now stable and supported:
549
+
550
+ ```ts
551
+ // next.config.ts
552
+ const nextConfig = {
553
+ reactCompiler: true,
554
+ };
555
+
556
+ export default nextConfig;
557
+ ```
558
+
559
+ Install the plugin:
560
+
561
+ ```bash
562
+ npm install -D babel-plugin-react-compiler
563
+ ```
564
+
565
+ **Note**: Expect higher compile times with React Compiler enabled.
566
+
567
+ ### 10. Scroll Behavior Override
568
+
569
+ Next.js no longer overrides `scroll-behavior: smooth` during navigation.
570
+
571
+ To restore previous behavior:
572
+
573
+ ```tsx
574
+ // app/layout.tsx
575
+ export default function RootLayout({ children }) {
576
+ return (
577
+ <html lang="en" data-scroll-behavior="smooth">
578
+ <body>{children}</body>
579
+ </html>
580
+ );
581
+ }
582
+ ```
583
+
584
+ ### 11. ESLint Migration
585
+
586
+ The `next lint` command has been removed. Migrate to ESLint CLI directly.
587
+
588
+ ```bash
589
+ # Run migration codemod
590
+ npx @next/codemod@canary next-lint-to-eslint-cli .
591
+ ```
592
+
593
+ Remove from `next.config.js`:
594
+
595
+ ```js
596
+ // Remove this
597
+ {
598
+ eslint: {
599
+ }
600
+ }
601
+ ```
602
+
603
+ **Action Items**:
604
+
605
+ - [ ] Run the ESLint migration codemod
606
+ - [ ] Remove `eslint` config from `next.config.js`
607
+ - [ ] Update CI scripts to use `eslint` directly instead of `next lint`
608
+
609
+ ### 12. Feature Removals
610
+
611
+ #### 12.1 AMP Support Removed
612
+
613
+ - All AMP APIs have been deleted
614
+ - Remove `useAmp` hook usage
615
+ - Remove `amp` config option
616
+ - Delete AMP-specific pages
617
+
618
+ #### 12.2 Runtime Configuration Removed
619
+
620
+ ```js
621
+ // BEFORE - Remove these
622
+ module.exports = {
623
+ serverRuntimeConfig: { dbUrl: process.env.DATABASE_URL },
624
+ publicRuntimeConfig: { apiUrl: '/api' },
625
+ };
626
+ ```
627
+
628
+ **Migration for server-side config**:
629
+
630
+ ```tsx
631
+ // Use environment variables directly
632
+ async function fetchData() {
633
+ const dbUrl = process.env.DATABASE_URL;
634
+ return await db.query(dbUrl, 'SELECT * FROM users');
635
+ }
636
+ ```
637
+
638
+ **Migration for client-side config**:
639
+
640
+ ```bash
641
+ # .env.local
642
+ NEXT_PUBLIC_API_URL="/api"
643
+ ```
644
+
645
+ ```tsx
646
+ 'use client';
647
+ export default function Component() {
648
+ const apiUrl = process.env.NEXT_PUBLIC_API_URL;
649
+ // ...
650
+ }
651
+ ```
652
+
653
+ #### 12.3 devIndicators Options Removed
654
+
655
+ Remove these from `next.config.js`:
656
+
657
+ - `appIsrStatus`
658
+ - `buildActivity`
659
+ - `buildActivityPosition`
660
+
661
+ #### 12.4 experimental.dynamicIO Renamed
662
+
663
+ ```js
664
+ // BEFORE
665
+ {
666
+ experimental: {
667
+ dynamicIO: true;
668
+ }
669
+ }
670
+
671
+ // AFTER
672
+ {
673
+ cacheComponents: true;
674
+ }
675
+ ```
676
+
677
+ #### 12.5 unstable_rootParams Removed
678
+
679
+ This API is removed. Await alternative API in a future minor release.
680
+
681
+ **Action Items**:
682
+
683
+ - [ ] Remove all AMP-related code
684
+ - [ ] Migrate runtime configuration to environment variables
685
+ - [ ] Remove deprecated devIndicators options
686
+ - [ ] Rename `dynamicIO` to `cacheComponents`
687
+
688
+ ### 13. Development Changes
689
+
690
+ #### 13.1 Concurrent dev and build
691
+
692
+ Development now outputs to `.next/dev` (separate from build).
693
+
694
+ **Update Turbopack tracing command**:
695
+
696
+ ```bash
697
+ npx next internal trace .next/dev/trace-turbopack
698
+ ```
699
+
700
+ ## Post-Migration Validation
701
+
702
+ ### 1. Run Build Per Project
703
+
704
+ ```bash
705
+ # Build each Next.js project individually
706
+ nx run PROJECT_NAME:build
707
+ ```
708
+
709
+ ### 2. Run Development Server
710
+
711
+ ```bash
712
+ # Start dev server to verify Turbopack works
713
+ nx run PROJECT_NAME:serve
714
+ ```
715
+
716
+ ### 3. Run All Affected Builds
717
+
718
+ ```bash
719
+ # Build all affected projects
720
+ nx affected -t build
721
+ ```
722
+
723
+ ### 4. Run Full Validation
724
+
725
+ ```bash
726
+ # Run full CI validation
727
+ nx prepush
728
+ ```
729
+
730
+ ### 5. Review Migration Checklist
731
+
732
+ - [ ] All async request APIs updated
733
+ - [ ] All page/layout components using params are async
734
+ - [ ] Turbopack configuration updated
735
+ - [ ] Middleware renamed to proxy
736
+ - [ ] Parallel routes have default.js files
737
+ - [ ] Image configuration updated
738
+ - [ ] Cache imports updated (removed unstable\_ prefix)
739
+ - [ ] AMP code removed
740
+ - [ ] Runtime config migrated to env vars
741
+ - [ ] ESLint configuration migrated
742
+ - [ ] All projects build successfully
743
+ - [ ] Development servers start correctly
744
+
745
+ ## Common Issues and Solutions
746
+
747
+ ### Issue: "cookies() expects to be called in a synchronous context"
748
+
749
+ **Solution**: Make the function async and await `cookies()`
750
+
751
+ ### Issue: "params should be awaited before accessing properties"
752
+
753
+ **Solution**: Add `await` before accessing `props.params`
754
+
755
+ ### Issue: Build fails with Turbopack
756
+
757
+ **Solution**: Add `--webpack` flag to build script, then gradually address Turbopack compatibility
758
+
759
+ ### Issue: Middleware not working after rename
760
+
761
+ **Solution**: Ensure both file and function are renamed from `middleware` to `proxy`
762
+
763
+ ### Issue: Parallel route not rendering
764
+
765
+ **Solution**: Add `default.tsx` file to the parallel route slot
766
+
767
+ ### Issue: Images with query strings not loading
768
+
769
+ **Solution**: Add `localPatterns` configuration for those images
770
+
771
+ ### Issue: TypeScript errors with params types
772
+
773
+ **Solution**: Run `npx next typegen` to generate type helpers, then use `PageProps`, `LayoutProps` types
774
+
775
+ ## Files to Review
776
+
777
+ Create a checklist of all files that need review:
778
+
779
+ ```bash
780
+ # Find all pages with potential params usage
781
+ find . -path "*/app/*" -name "page.tsx" -o -name "page.ts" | xargs grep -l "params\|searchParams"
782
+
783
+ # Find all layouts
784
+ find . -path "*/app/*" -name "layout.tsx" -o -name "layout.ts"
785
+
786
+ # Find all route handlers
787
+ find . -path "*/app/*" -name "route.ts" -o -name "route.tsx"
788
+
789
+ # Find middleware files
790
+ find . -name "middleware.ts" -o -name "middleware.js"
791
+
792
+ # Find files using cookies/headers
793
+ rg "from 'next/headers'" --type ts --type tsx
794
+
795
+ # Find next.config files
796
+ find . -name "next.config.*" -not -path "*/node_modules/*"
797
+
798
+ # Find parallel routes
799
+ find . -path "*/app/@*" -type d
800
+ ```
801
+
802
+ ## Migration Strategy for Large Workspaces
803
+
804
+ 1. **Migrate in phases**: Start with a small project, validate, then expand
805
+ 2. **Use the codemod**: Run `npx @next/codemod@canary upgrade latest` for automated fixes
806
+ 3. **Generate types**: Run `npx next typegen` for type-safe migrations
807
+ 4. **Run tests frequently**: After each configuration change, run affected tests
808
+ 5. **Document issues**: Keep track of project-specific issues and solutions
809
+
810
+ ## Useful Commands During Migration
811
+
812
+ ```bash
813
+ # Find all Next.js projects
814
+ nx show projects --with-target build
815
+
816
+ # Build specific project
817
+ nx build PROJECT_NAME
818
+
819
+ # Serve specific project
820
+ nx serve PROJECT_NAME
821
+
822
+ # Build all affected
823
+ nx affected -t build
824
+
825
+ # View project details
826
+ nx show project PROJECT_NAME --web
827
+
828
+ # Clear Nx cache if needed
829
+ nx reset
830
+ ```
831
+
832
+ ---
833
+
834
+ ## Notes for LLM Execution
835
+
836
+ When executing this migration:
837
+
838
+ 1. **Work systematically**: Complete one category before moving to the next
839
+ 2. **Test after each change**: Don't batch all changes without validation
840
+ 3. **Keep user informed**: Report progress through each section
841
+ 4. **Handle errors promptly**: If builds fail, fix immediately before proceeding
842
+ 5. **Use the codemod first**: Let `@next/codemod` handle repetitive async/await changes
843
+ 6. **Prioritize breaking changes**: Focus on async APIs first as they're most impactful
844
+ 7. **Create meaningful commits**: Group related changes together with clear messages
845
+ 8. **Use TodoWrite tool**: Track migration progress for visibility