Mejores Prácticas de Patrones de Next.js
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
Busca en todas las páginas de la documentación
Un resumen condensado de las 25 mejores prácticas más importantes extraídas de cada página en esta sección.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
import "server-only" en la parte superior de cualquier módulo que toque AUTH_SECRET, URLs de base de datos o claves de firma para que un Client Component que lo importe falle la compilación en lugar de filtrar el valor al paquete del navegador.httpOnly: true para bloquear el acceso de JS, secure: true en producción para requerir HTTPS, y sameSite: "lax" para protección básica de CSRF; sameSite: "none" además requiere secure: true o el navegador descarta la cookie completamente.NextRequest/NextResponse de next/server para obtener .nextUrl, .cookies, .geo, y ayudantes estáticos como NextResponse.json() sin tener que reconstruirlos sobre la Request Web.{ params: Promise<{ ... }> }; desestructurar sin await params produce una Promise y tu búsqueda retorna silenciosamente undefined.await request.json() lance una excepción, así que envu élvelo y retorna { error: "Invalid JSON" } con estado 400 - o valida con un safeParse de Zod para entrada completamente tipada.new NextResponse(null, { status: 204 }); NextResponse.json(null, { status: 204 }) envía la cadena "null" como cuerpo y viola el contrato 204.updateMany({ where: { credits: { gt: 0 } }, data: { credits: { decrement: 1 } } }) o "incrementa primero, luego verifica, reviertete en desbordamiento" para cerrar la ventana TOCTOU entre lectura y escritura.NEXT_PUBLIC_ se inserta en el paquete del cliente en tiempo de compilación, así que reserva esto para claves publicables y URLs públicas - las URLs de base de datos, claves API y secretos de firma deben permanecer solo en servidor.process.env[varName] siempre es undefined en código de cliente - solo referencias literales como process.env.NEXT_PUBLIC_APP_URL se insertan.process.env a través de un esquema Zod en lib/env.ts para que variables faltantes o malformadas fallen rápidamente con un mensaje claro antes de la primera solicitud, y obtengas un objeto env completamente tipado de forma gratuita.error.tsx necesita "use client" en la parte superior; sin ella la compilación falla y ningún límite se instala para ese segmento.global-error.tsx reemplaza el documento completo, así que debe renderizar <html><body>…</body></html>; también solo se activa en producción (dev muestra la superposición de Next.js).{ success: true; data: T } | { success: false; error: string } para fallos de validación esperados, y reserva throw para errores inesperados que deben activar el error.tsx más cercano.redirect() (y notFound()) lanzan un error de centinela NEXT_REDIRECT, así que un try/catch circundante traga la navegación - coloca la llamada después de toda la lógica recuperable o relanza el centinela.output: "standalone" produce un servidor autónomo minimalista y autónomo, pero .next/static y public/ no se incluyen - cópialos en el directorio standalone (o frente con un CDN/proxy inverso) o los activos estáticos retornarán 404.127.0.0.1 de forma predeterminada, que es inaccesible desde fuera de un contenedor; establece ENV HOSTNAME="0.0.0.0" (y ENV PORT=3000) en el Dockerfile para que el mapeo de puertos funcione.runtime = "edge" se ejecuta en un aislamiento V8 sin las built-ins de Node - sin fs, path, child_process o Buffer, y debes usar globalThis.crypto; retrocede a "nodejs" siempre que necesites esas APIs.openGraph, twitter y alternates se resuelven contra metadataBase; sin metadataBase: new URL("https://myapp.com") tus imágenes OG y canónicas se envían como rutas relativas rotas.async generateMetadata({ params }) (params es una Promise en Next.js 15+) y extiende la antecesor a través del argumento ResolvingMetadata en lugar de duplicar campos.app/sitemap.ts sirve automáticamente /sitemap.xml y app/robots.ts sirve automáticamente /robots.txt; divide en múltiples Route Handlers de mapa del sitio una vez que un sitio excede el límite de mapa del sitio de 50,000 URLs._next, api y archivos con extensiones (p. ej., matcher: ["/((?!_next|api|favicon.ico).*)"]) o redirige activos estáticos en rutas con prefijo de configuración regional y rompe la página.generateStaticParams; las configuraciones regionales faltantes retornan silenciosamente 404 en producción a menos que dynamicParams esté habilitado.cookies(), headers(), revalidatePath y revalidateTag lanzan excepción fuera del contexto de solicitud de Next.js, así que córtalos con vi.mock("next/headers", …) / vi.mock("next/cache", …) antes de importar el módulo bajo prueba.const jsx = await PostList(); render(jsx) en lugar de render(<PostList />); también simula con vi.mock() antes de import() dinámico para asegurar que la simulación gane.Revisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥