nextjs15_misc 14 Q&As

Nextjs15 Misc FAQ & Answers

14 expert Nextjs15 Misc answers researched from official documentation. Every answer cites authoritative sources you can verify.

unknown

14 questions
A

Next.js 15 made request APIs async - must await: import { cookies, headers } from 'next/headers'; export default async function Page({ params, searchParams }) { const cookieStore = await cookies(); const token = cookieStore.get('token')?.value; const headersList = await headers(); const userAgent = headersList.get('user-agent'); const resolvedParams = await params; const resolvedSearchParams = await searchParams; return

{resolvedParams.id}
; }. Breaking change from Next.js 14 (previously synchronous). Enables async rendering - React can render synchronous parts immediately while fetching request data. Temporary backward compatibility: can access synchronously with warnings until Next.js 16. Migration codemod available: npx @next/codemod@canary next-async-request-api. Affects: cookies(), draftMode(), headers(), params props, searchParams props. Production: migrate gradually, test thoroughly, use codemod for automation.

99% confidence
A

Next.js 15 major change: fetch requests NOT cached by default (breaking from v14). Opt-in to caching: fetch(url, { cache: 'force-cache' }) or export const dynamic = 'force-static' at page level. Time-based revalidation: fetch(url, { next: { revalidate: 60 } }) for 60-second cache. On-demand revalidation: use revalidatePath('/path') or revalidateTag('tag') in Server Actions. unstable_cache deprecated - replaced with use cache directive (experimental): import { unstable_cache } from 'next/cache'; const getData = unstable_cache(async () => { const data = await db.query(); return data; }, ['cache-key'], { revalidate: 3600, tags: ['data'] }). Production: opt into caching explicitly for performance, use tags for granular invalidation, monitor cache hit rates. Router cache also less sticky in v15. Default no-cache prevents stale data but requires explicit optimization.

99% confidence
A

Use generateViewport export instead of deprecated metadata fields: export function generateViewport() { return { width: 'device-width', initialScale: 1, themeColor: [{ media: '(prefers-color-scheme: light)', color: '#ffffff' }, { media: '(prefers-color-scheme: dark)', color: '#000000' }], colorScheme: 'light dark' }; }. Breaking change in Next.js 14+: themeColor, viewport, colorScheme removed from metadata object. Static viewport: export const viewport = { width: 'device-width', initialScale: 1 }. Dynamic viewport: use generateViewport function with runtime data. Benefits: media queries for theme-color (light/dark mode), separation of concerns (metadata vs viewport). charset automatically set by Next.js. Production: migrate from metadata.viewport to separate viewport export, use generateViewport for dynamic values, support prefers-color-scheme media queries. Works with PWA manifests.

99% confidence
A

Use remotePatterns (domains deprecated in v14) for external images: // next.config.js: module.exports = { images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com', pathname: '/images/**' }], formats: ['image/avif', 'image/webp'] } }. Custom loader for CDN: // next.config.js: images: { loader: 'custom', loaderFile: './imageLoader.js' }. imageLoader.js: export default function imageLoader({ src, width, quality }) { return https://cdn.example.com/${src}?w=${width}&q=${quality || 75}; }. remotePatterns provides security (protocol, hostname, pathname, port filtering). Image component: Photo. Automatic: WebP/AVIF formats, lazy loading, responsive sizes. Production: use remotePatterns not domains, configure CDN loader for external optimization, set formats priority AVIF > WebP > JPEG.

99% confidence
A

Define route handlers in app/api/route.ts: export async function GET(request: Request) { const headersList = await headers(); const auth = headersList.get('authorization'); const { searchParams } = new URL(request.url); const id = searchParams.get('id'); const data = await fetchData(id); return Response.json(data, { headers: { 'Cache-Control': 'no-cache' } }); }. POST handler: export async function POST(request: Request) { const body = await request.json(); const result = await db.insert(body); return Response.json({ id: result.id }, { status: 201 }); }. Breaking change: GET handlers NOT cached by default in v15 (was cached in v14). Opt-in caching: export const dynamic = 'force-static'. Supported methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. headers() must be awaited (async API). Production: handle CORS, validate inputs, use appropriate status codes, return NextResponse for advanced features (cookies, redirects).

99% confidence
A

Create instrumentation.ts in root (now stable, no experimental flag needed): export async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { const { NodeSDK } = await import('@opentelemetry/sdk-node'); const sdk = new NodeSDK({ tracing: { /* config */ } }); sdk.start(); } }. New onRequestError for error tracking: export async function onRequestError(err, request, context) { await fetch('https://logger.com/errors', { method: 'POST', body: JSON.stringify({ error: err.message, path: request.url, digest: err.digest }) }); }. register() called once on server init. Use for: OpenTelemetry setup, performance monitoring, custom instrumentation. Runtime-specific: check NEXT_RUNTIME for nodejs vs edge. File location: root or src/, not inside app/pages. Production: integrate with Sentry, Datadog, or OpenTelemetry, track server errors with onRequestError, initialize monitoring SDKs. Works with Vercel @vercel/otel package.

99% confidence
A

TypeScript config support (new): next.config.ts with type safety: import type { NextConfig } from 'next'; const config: NextConfig = { reactStrictMode: true, bundlePagesRouterDependencies: true }; export default config. bundlePagesRouterDependencies stable: renamed from bundlePagesExternals, automatically bundles external packages in Pages Router. serverExternalPackages: ['pkg'] to exclude specific packages. ESLint 9 support: Next.js 15 supports ESLint 9 (backward compatible with v8), upgraded eslint-plugin-react-hooks to v5.0.0 with new Hooks rules. Setup: npx create-next-app@latest generates next.config.ts by default. Migration: rename next.config.js to .ts, add type imports, enable strict TypeScript checks. Production: use TypeScript config for type safety, enable bundlePagesRouterDependencies for optimized Pages Router, upgrade to ESLint 9 (v8 EOL Oct 2024). Known issue: reactStrictMode may not work in some 15.x versions.

99% confidence
A

Next.js 15 made request APIs async - must await: import { cookies, headers } from 'next/headers'; export default async function Page({ params, searchParams }) { const cookieStore = await cookies(); const token = cookieStore.get('token')?.value; const headersList = await headers(); const userAgent = headersList.get('user-agent'); const resolvedParams = await params; const resolvedSearchParams = await searchParams; return

{resolvedParams.id}
; }. Breaking change from Next.js 14 (previously synchronous). Enables async rendering - React can render synchronous parts immediately while fetching request data. Temporary backward compatibility: can access synchronously with warnings until Next.js 16. Migration codemod available: npx @next/codemod@canary next-async-request-api. Affects: cookies(), draftMode(), headers(), params props, searchParams props. Production: migrate gradually, test thoroughly, use codemod for automation.

99% confidence
A

Next.js 15 major change: fetch requests NOT cached by default (breaking from v14). Opt-in to caching: fetch(url, { cache: 'force-cache' }) or export const dynamic = 'force-static' at page level. Time-based revalidation: fetch(url, { next: { revalidate: 60 } }) for 60-second cache. On-demand revalidation: use revalidatePath('/path') or revalidateTag('tag') in Server Actions. unstable_cache deprecated - replaced with use cache directive (experimental): import { unstable_cache } from 'next/cache'; const getData = unstable_cache(async () => { const data = await db.query(); return data; }, ['cache-key'], { revalidate: 3600, tags: ['data'] }). Production: opt into caching explicitly for performance, use tags for granular invalidation, monitor cache hit rates. Router cache also less sticky in v15. Default no-cache prevents stale data but requires explicit optimization.

99% confidence
A

Use generateViewport export instead of deprecated metadata fields: export function generateViewport() { return { width: 'device-width', initialScale: 1, themeColor: [{ media: '(prefers-color-scheme: light)', color: '#ffffff' }, { media: '(prefers-color-scheme: dark)', color: '#000000' }], colorScheme: 'light dark' }; }. Breaking change in Next.js 14+: themeColor, viewport, colorScheme removed from metadata object. Static viewport: export const viewport = { width: 'device-width', initialScale: 1 }. Dynamic viewport: use generateViewport function with runtime data. Benefits: media queries for theme-color (light/dark mode), separation of concerns (metadata vs viewport). charset automatically set by Next.js. Production: migrate from metadata.viewport to separate viewport export, use generateViewport for dynamic values, support prefers-color-scheme media queries. Works with PWA manifests.

99% confidence
A

Use remotePatterns (domains deprecated in v14) for external images: // next.config.js: module.exports = { images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com', pathname: '/images/**' }], formats: ['image/avif', 'image/webp'] } }. Custom loader for CDN: // next.config.js: images: { loader: 'custom', loaderFile: './imageLoader.js' }. imageLoader.js: export default function imageLoader({ src, width, quality }) { return https://cdn.example.com/${src}?w=${width}&q=${quality || 75}; }. remotePatterns provides security (protocol, hostname, pathname, port filtering). Image component: Photo. Automatic: WebP/AVIF formats, lazy loading, responsive sizes. Production: use remotePatterns not domains, configure CDN loader for external optimization, set formats priority AVIF > WebP > JPEG.

99% confidence
A

Define route handlers in app/api/route.ts: export async function GET(request: Request) { const headersList = await headers(); const auth = headersList.get('authorization'); const { searchParams } = new URL(request.url); const id = searchParams.get('id'); const data = await fetchData(id); return Response.json(data, { headers: { 'Cache-Control': 'no-cache' } }); }. POST handler: export async function POST(request: Request) { const body = await request.json(); const result = await db.insert(body); return Response.json({ id: result.id }, { status: 201 }); }. Breaking change: GET handlers NOT cached by default in v15 (was cached in v14). Opt-in caching: export const dynamic = 'force-static'. Supported methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. headers() must be awaited (async API). Production: handle CORS, validate inputs, use appropriate status codes, return NextResponse for advanced features (cookies, redirects).

99% confidence
A

Create instrumentation.ts in root (now stable, no experimental flag needed): export async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { const { NodeSDK } = await import('@opentelemetry/sdk-node'); const sdk = new NodeSDK({ tracing: { /* config */ } }); sdk.start(); } }. New onRequestError for error tracking: export async function onRequestError(err, request, context) { await fetch('https://logger.com/errors', { method: 'POST', body: JSON.stringify({ error: err.message, path: request.url, digest: err.digest }) }); }. register() called once on server init. Use for: OpenTelemetry setup, performance monitoring, custom instrumentation. Runtime-specific: check NEXT_RUNTIME for nodejs vs edge. File location: root or src/, not inside app/pages. Production: integrate with Sentry, Datadog, or OpenTelemetry, track server errors with onRequestError, initialize monitoring SDKs. Works with Vercel @vercel/otel package.

99% confidence
A

TypeScript config support (new): next.config.ts with type safety: import type { NextConfig } from 'next'; const config: NextConfig = { reactStrictMode: true, bundlePagesRouterDependencies: true }; export default config. bundlePagesRouterDependencies stable: renamed from bundlePagesExternals, automatically bundles external packages in Pages Router. serverExternalPackages: ['pkg'] to exclude specific packages. ESLint 9 support: Next.js 15 supports ESLint 9 (backward compatible with v8), upgraded eslint-plugin-react-hooks to v5.0.0 with new Hooks rules. Setup: npx create-next-app@latest generates next.config.ts by default. Migration: rename next.config.js to .ts, add type imports, enable strict TypeScript checks. Production: use TypeScript config for type safety, enable bundlePagesRouterDependencies for optimized Pages Router, upgrade to ESLint 9 (v8 EOL Oct 2024). Known issue: reactStrictMode may not work in some 15.x versions.

99% confidence