$npx -y skills add jgamaraalv/ts-dev-kit --skill nextjs-best-practicesNext.js App Router best practices — file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling. Use when writing, reviewing, or debugging Next.js App Router code.
| 1 | # Next.js Best Practices |
| 2 | |
| 3 | Apply these rules when writing or reviewing Next.js code. |
| 4 | |
| 5 | > **Note:** Next.js 16 renamed `middleware.ts` to `proxy.ts`. Verify `proxy.ts` support in your version; `middleware.ts` remains the stable API. |
| 6 | |
| 7 | <references> |
| 8 | |
| 9 | ## File Conventions |
| 10 | |
| 11 | See [file-conventions.md](references/file-conventions.md) for: |
| 12 | |
| 13 | - Project structure and special files |
| 14 | - Route segments (dynamic, catch-all, groups) |
| 15 | - Parallel and intercepting routes |
| 16 | - Middleware rename in v16 (middleware → proxy) |
| 17 | |
| 18 | ## RSC Boundaries |
| 19 | |
| 20 | Detect invalid React Server Component patterns. |
| 21 | |
| 22 | See [rsc-boundaries.md](references/rsc-boundaries.md) for: |
| 23 | |
| 24 | - Async client component detection (invalid) |
| 25 | - Non-serializable props detection |
| 26 | - Server Action exceptions |
| 27 | |
| 28 | ## Async Patterns |
| 29 | |
| 30 | Next.js 16.1.6+ async API changes. |
| 31 | |
| 32 | See [async-patterns.md](references/async-patterns.md) for: |
| 33 | |
| 34 | - Async `params` and `searchParams` |
| 35 | - Async `cookies()` and `headers()` |
| 36 | - Migration codemod |
| 37 | |
| 38 | ## Runtime Selection |
| 39 | |
| 40 | See [runtime-selection.md](references/runtime-selection.md) for: |
| 41 | |
| 42 | - Default to Node.js runtime |
| 43 | - When Edge runtime is appropriate |
| 44 | |
| 45 | ## Directives |
| 46 | |
| 47 | See [directives.md](references/directives.md) for: |
| 48 | |
| 49 | - `'use client'`, `'use server'` (React) |
| 50 | - `'use cache'` (Next.js) |
| 51 | |
| 52 | ## Functions |
| 53 | |
| 54 | See [functions.md](references/functions.md) for: |
| 55 | |
| 56 | - Navigation hooks: `useRouter`, `usePathname`, `useSearchParams`, `useParams` |
| 57 | - Server functions: `cookies`, `headers`, `draftMode`, `after` |
| 58 | - Generate functions: `generateStaticParams`, `generateMetadata` |
| 59 | |
| 60 | ## Error Handling |
| 61 | |
| 62 | See [error-handling.md](references/error-handling.md) for: |
| 63 | |
| 64 | - `error.tsx`, `global-error.tsx`, `not-found.tsx` |
| 65 | - `redirect`, `permanentRedirect`, `notFound` |
| 66 | - `forbidden`, `unauthorized` (auth errors) |
| 67 | - `unstable_rethrow` for catch blocks |
| 68 | |
| 69 | ## Data Patterns |
| 70 | |
| 71 | See [data-patterns.md](references/data-patterns.md) for: |
| 72 | |
| 73 | - Server Components vs Server Actions vs Route Handlers |
| 74 | - Avoiding data waterfalls (`Promise.all`, Suspense, preload) |
| 75 | - Client component data fetching |
| 76 | |
| 77 | ## Route Handlers |
| 78 | |
| 79 | See [route-handlers.md](references/route-handlers.md) for: |
| 80 | |
| 81 | - `route.ts` basics |
| 82 | - GET handler conflicts with `page.tsx` |
| 83 | - Environment behavior (no React DOM) |
| 84 | - When to use vs Server Actions |
| 85 | |
| 86 | ## Metadata & OG Images |
| 87 | |
| 88 | See [metadata.md](references/metadata.md) for: |
| 89 | |
| 90 | - Static and dynamic metadata |
| 91 | - `generateMetadata` function |
| 92 | - OG image generation with `next/og` |
| 93 | - File-based metadata conventions |
| 94 | |
| 95 | ## Image Optimization |
| 96 | |
| 97 | See [image.md](references/image.md) for: |
| 98 | |
| 99 | - Always use `next/image` over `<img>` |
| 100 | - Remote images configuration |
| 101 | - Responsive `sizes` attribute |
| 102 | - Blur placeholders |
| 103 | - Priority loading for LCP |
| 104 | |
| 105 | ## Font Optimization |
| 106 | |
| 107 | See [font.md](references/font.md) for: |
| 108 | |
| 109 | - `next/font` setup |
| 110 | - Google Fonts, local fonts |
| 111 | - Tailwind CSS integration |
| 112 | - Preloading subsets |
| 113 | |
| 114 | ## Bundling |
| 115 | |
| 116 | See [bundling.md](references/bundling.md) for: |
| 117 | |
| 118 | - Server-incompatible packages |
| 119 | - CSS imports (not link tags) |
| 120 | - Polyfills (already included) |
| 121 | - ESM/CommonJS issues |
| 122 | - Bundle analysis |
| 123 | |
| 124 | ## Scripts |
| 125 | |
| 126 | See [scripts.md](references/scripts.md) for: |
| 127 | |
| 128 | - `next/script` vs native script tags |
| 129 | - Inline scripts need `id` |
| 130 | - Loading strategies |
| 131 | - Google Analytics with `@next/third-parties` |
| 132 | |
| 133 | ## Hydration Errors |
| 134 | |
| 135 | See [hydration-error.md](references/hydration-error.md) for: |
| 136 | |
| 137 | - Common causes (browser APIs, dates, invalid HTML) |
| 138 | - Debugging with error overlay |
| 139 | - Fixes for each cause |
| 140 | |
| 141 | ## Suspense Boundaries |
| 142 | |
| 143 | See [suspense-boundaries.md](references/suspense-boundaries.md) for: |
| 144 | |
| 145 | - CSR bailout with `useSearchParams` and `usePathname` |
| 146 | - Which hooks require Suspense boundaries |
| 147 | |
| 148 | ## Parallel & Intercepting Routes |
| 149 | |
| 150 | See [parallel-routes.md](references/parallel-routes.md) for: |
| 151 | |
| 152 | - Modal patterns with `@slot` and `(.)` interceptors |
| 153 | - `default.tsx` for fallbacks |
| 154 | - Closing modals correctly with `router.back()` |
| 155 | |
| 156 | ## Self-Hosting |
| 157 | |
| 158 | See [self-hosting.md](references/self-hosting.md) for: |
| 159 | |
| 160 | - `output: 'standalone'` for Docker |
| 161 | - Cache handlers for multi-instance ISR |
| 162 | - What works vs needs extra setup |
| 163 | |
| 164 | ## Debug Tricks |
| 165 | |
| 166 | See [debug-tricks.md](references/debug-tricks.md) for: |
| 167 | |
| 168 | - MCP endpoint for AI-assisted debugging |
| 169 | - Rebuild specific routes with `--debug-build-paths` |
| 170 | |
| 171 | </references> |