Next.js
Guía rápida de Next.js 16: 75 patrones de App Router para producción
Una referencia práctica de Next.js 16 con 75 comandos, convenciones de archivos, patrones de Server Components, APIs de caché, campos SEO, comprobaciones de seguridad y consejos de despliegue.
Usa esta referencia mientras desarrollas proyectos App Router de Next.js 16. Cada entrada responde a una pregunta concreta, con código copiable cuando importa la sintaxis.
Configuración y comandos del proyecto
Inicia, inspecciona y actualiza un proyecto Next.js 16 con comandos reproducibles. Los ejemplos usan npm, pero los conceptos del framework son independientes del gestor de paquetes.
- 1
Crear un nuevo proyecto App Router
create-next-app configura Next.js, React, TypeScript y las herramientas elegidas. Guarda package-lock.json junto al proyecto en commits.
npx create-next-app@latest my-app --ts --app --src-dir - 2
Usa la versión mínima actual de Node.js
Next.js 16 requiere Node.js 20.9 o posterior. Fija una versión compatible en desarrollo local y CI para que las compilaciones no dependan del valor predeterminado cambiante del ejecutor.
- 3
Conoce los cuatro scripts normales
next dev inicia el desarrollo, next build crea la salida de producción, next start la sirve y el linter configurado se ejecuta por separado.
"scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint ." } - 4
Instala de forma reproducible en CI
Usa npm ci cuando package-lock.json esté guardado en commits. Rechaza las discrepancias del archivo de bloqueo e instala el árbol resuelto de dependencias sin reescribirlo.
npm ci && npm run build - 5
Usa Turbopack por defecto
En Next.js 16, next dev y next build usan Turbopack por defecto. Retira las opciones antiguas --turbo, salvo que el script necesite admitir otra versión.
- 6
Conserva temporalmente una compilación webpack
Un proyecto con configuración webpack personalizada puede desactivar explícitamente el compilador predeterminado mientras la migra. Prueba la salida y el rendimiento antes de cambiar el compilador de producción.
next build --webpack - 7
Mantén el código de la aplicación en src
src/app y src/lib separan el código de la aplicación de la configuración raíz. El directorio public y archivos como next.config.ts permanecen en la raíz del proyecto.
- 8
Usa un alias de importación
Un alias estable evita rutas relativas largas cuando el código se mueve entre carpetas de rutas. Mantén el alias en tsconfig.json o jsconfig.json.
import { getUser } from "@/lib/data";
Páginas, layouts y enrutamiento
App Router es un router basado en el sistema de archivos. Estas convenciones controlan las URLs, la interfaz compartida, los parámetros dinámicos y la navegación avanzada.
- 9
Crear una página
Un archivo page.tsx hace públicamente accesible la ruta de su carpeta. La exportación predeterminada es la interfaz de esa URL.
export default function Page() { return <h1>About</h1>; } - 10
Crea el layout raíz obligatorio
app/layout.tsx envuelve todas las rutas y debe renderizar html y body. Coloca aquí CSS global, idioma, proveedores de todo el sitio y metadatos predeterminados.
- 11
Anida layouts por segmento de ruta
Un layout dentro de app/dashboard envuelve la página del panel y todos sus descendientes. Los layouts persisten durante la navegación del cliente dentro de su subárbol.
- 12
Agrupa rutas sin cambiar la URL
Los paréntesis crean un grupo de rutas. app/(marketing)/pricing/page.tsx sigue resolviendo a /pricing.
app/(marketing)/pricing/page.tsx - 13
Crear un segmento dinámico
Los corchetes capturan un segmento URL. En Next.js 16, espera params antes de leer el valor.
export default async function Page({ params }) { const { slug } = await params; return <h1>{slug}</h1>; } - 14
Captura varios segmentos
[...parts] es un catch-all obligatorio y [[...parts]] es opcional. Úsalos para documentación jerárquica u otras rutas cuya profundidad dependa de los datos.
- 15
Genera de antemano las rutas dinámicas conocidas
generateStaticParams devuelve objetos de parámetros para las rutas que Next.js debe generar durante la compilación.
export function generateStaticParams() { return posts.map((post) => ({ slug: post.slug })); } - 16
Rechazar caminos dinámicos desconocidos
Configura dynamicParams como false cuando deban resolverse solo los valores devueltos por generateStaticParams. Los demás valores de parámetros devuelven 404.
export const dynamicParams = false; - 17
Renderiza un recurso ausente
Llama a notFound cuando exista la ruta, pero no la entidad solicitada. Next.js renderiza el límite not-found.tsx más cercano.
if (!post) notFound(); - 18
Reiniciar el estado con una plantilla
template.tsx se parece a un layout, pero vuelve a montarse al navegar. Úsalo cuando el estado y los efectos deban reiniciarse; conserva las estructuras persistentes en los layouts.
- 19
Renderiza slots simultáneos de rutas
Carpetas como @team y @analytics definen slots de rutas paralelas que se pasan a un layout padre. Proporciona estados alternativos default.tsx para los slots sin coincidencia al navegar mediante una carga completa.
- 20
Abrir una ruta como modal
Las rutas interceptadas pueden mostrar otra ruta dentro del layout actual durante la navegación del cliente y conservar su resultado de página completa para las recargas y los enlaces compartidos.
Server Components y Client Components
Server Components es la opción predeterminada de App Router. Añade JavaScript del navegador solo a los componentes que necesiten interacción o APIs exclusivas del navegador.
- 21
Mantén las páginas en el servidor por defecto
Un Server Component puede esperar datos, usar variables de entorno privadas y renderizar sin enviar su código al navegador.
- 22
Declara un Client Component
Coloca la directiva antes de las importaciones. El límite del cliente incluye ese módulo y el grafo de dependencias de cliente que importa.
"use client"; import { useState } from "react"; - 23
Usa componentes de cliente para la interacción
El estado, los efectos, los handlers de eventos, los hooks personalizados, window, localStorage y las demás APIs del navegador pertenecen a Client Components.
- 24
Usa componentes de servidor para el trabajo privado
Las consultas de base de datos, las credenciales de servicio, las bibliotecas grandes exclusivas del servidor y la mayor parte del renderizado de contenido pertenecen a Server Components o módulos exclusivos del servidor.
- 25
Pasa props serializables a los clientes
Las cadenas, números, booleanos, arrays, objetos simples y valores React admitidos pueden cruzar el límite. Selecciona los datos cuidadosamente y no pases registros privados completos.
- 26
Marca los módulos privados con server-only
La importación por efectos secundarios hace fallar una importación de cliente durante la compilación y protege el código de acceso a datos del uso accidental en el navegador.
import "server-only"; - 27
Desplaza hacia abajo el límite del cliente
Mantén la página y el layout renderizados en el servidor, y aísla un buscador, menú, selector o gráfico como el Client Component práctico más pequeño.
- 28
Pasa la interfaz del servidor mediante children del cliente
Un Client Component puede recibir un Server Component como hijo o como otra prop. Esto mantiene el subárbol renderizado en el servidor fuera del grafo de módulos propio del cliente.
- 29
Añade los proveedores lo más abajo posible
El contexto no está disponible en Server Components. Renderiza un proveedor Client Component específico alrededor del subárbol que lo usa, en lugar de envolver todo el documento por defecto.
Obtención de datos, transmisión y caché
Elige deliberadamente la vigencia. Cache Components de Next.js 16 es opcional; la referencia señala las APIs que requieren esa configuración.
- 30
Obtén datos en un Server Component asíncrono
Llama a una API, ORM o base de datos desde el componente que renderiza el resultado. No necesitas un Route Handler interno solo para llamar a tu propio servidor.
export default async function Page() { const products = await getProducts(); return <ProductList products={products} />; } - 31
Inicia juntas las tareas independientes
Promise.all evita una cascada innecesaria de solicitudes cuando ninguna operación necesita el resultado de la otra.
const [user, projects] = await Promise.all([ getUser(), getProjects(), ]); - 32
Transmite con un archivo de carga de ruta
loading.tsx envuelve el segmento en un límite Suspense y ofrece inmediatamente una interfaz provisional durante la navegación y el renderizado de la solicitud.
- 33
Transmite una sección lenta
Coloca Suspense alrededor del componente lento para que el resto de la página se renderice primero. Haz que el estado provisional tenga las dimensiones finales.
<Suspense fallback={<ActivitySkeleton />}> <RecentActivity /> </Suspense> - 34
Memoiza un ciclo de renderizado
React cache puede deduplicar la misma función de datos del servidor con los mismos argumentos durante un renderizado. No es una caché persistente de datos de la aplicación.
import { cache } from "react"; export const getUser = cache(async (id) => db.user.findUnique({ where: { id } })); - 35
Activa Cache Components
Las APIs use cache de Next.js 16 requieren el ajuste cacheComponents. Migra deliberadamente porque cambia el comportamiento de renderizado y caché.
const nextConfig = { cacheComponents: true }; export default nextConfig; - 36
Guarda en caché una función asíncrona
Con Cache Components activo, coloca use cache al principio del cuerpo de una función o componente asíncrono. Los argumentos serializables forman parte de la clave de caché.
export async function getProducts() { "use cache"; return db.product.findMany(); } - 37
Define la vigencia de la caché
cacheLife acepta un perfil con nombre o tiempos personalizados. Elige la vigencia según cuánto pueda quedar obsoleto el contenido, no por comodidad.
"use cache"; cacheLife("hours"); - 38
Etiqueta el trabajo relacionado en caché
cacheTag asigna a varias entradas una etiqueta compartida de invalidación, como products o post-42.
"use cache"; cacheTag("products"); - 39
Haz caducar una ruta
Llama a revalidatePath desde una Server Function o un Route Handler después de un cambio que deje obsoleta una página o layout.
revalidatePath("/blog"); - 40
Revalida por etiqueta
Usa revalidateTag cuando el contenido etiquetado admita stale-while-revalidate. Elige el perfil de caché que corresponda al requisito de vigencia.
- 41
Lee tu propia escritura con updateTag
Llama a updateTag dentro de una Server Action cuando el usuario de la acción deba ver datos etiquetados actualizados inmediatamente después de la mutación.
await savePost(input); updateTag("posts");
Formularios, mutaciones y Route Handlers
Las escrituras necesitan validación, autorización, errores predecibles y una actualización explícita de caché. Las interfaces HTTP también necesitan la seguridad habitual de endpoints.
- 42
Declara una Server Action
Coloca use server al principio de una función asíncrona o módulo de acciones. Trata las Server Actions exportadas como endpoints de mutación que pueden llamarse remotamente.
"use server"; export async function createPost(formData: FormData) { // validate, authorize, mutate, invalidate } - 43
Vincula una acción a un formulario
Un formulario puede llamar a una Server Action sin un handler personalizado de envío en el cliente. El comportamiento nativo del formulario también permite una mejora progresiva.
<form action={createPost}>...</form> - 44
Validar FormData en el servidor
Trata como no fiables los nombres, IDs, archivos, campos ocultos y validaciones de cliente. Analízalos conforme a un esquema explícito antes de escribir.
- 45
Devuelve errores esperados del formulario
Usa un resultado serializable y useActionState para los errores de validación o negocio que pueda corregir el usuario. No lances excepciones para todos los resultados esperados.
- 46
Mostrar estado de formulario pendiente
useFormStatus lee el estado de envío del formulario padre. Desactiva envíos repetidos y muestra en el botón una etiqueta fiel al estado pendiente.
- 47
Crea un Route Handler
route.ts exporta funciones de verbos HTTP y usa las APIs Web Request y Response. Un archivo route.ts no puede compartir segmento con page.tsx.
export async function GET() { return Response.json({ status: "ok" }); } - 48
Lee un parámetro dinámico de Route Handler
params del contexto de ruta es asíncrono en Next.js actual. Espéralo antes de consultar el recurso.
export async function GET(request, { params }) { const { id } = await params; return Response.json(await getItem(id)); } - 49
Redirigir después de una mutación
Usa redirect para una navegación temporal tras una creación o actualización correcta, y permanentRedirect solo si el recurso tiene una nueva URL canónica permanente.
redirect("/dashboard"); - 50
Mantén seguros los reintentos
Los webhooks y las solicitudes de red pueden llegar más de una vez. Guarda los IDs de evento del proveedor o las claves de idempotencia antes de repetir pagos, correos u otros efectos secundarios.
SEO, imágenes, fuentes y scripts
Next.js puede generar etiquetas head y archivos de rastreadores desde el código de rutas. La página visible sigue necesitando contenido específico y útil y una estructura semántica.
- 58
Establecer metadatos estáticos
Exporta metadata desde un layout o página Server Component cuando los valores no dependan de los datos de la ruta.
export const metadata = { title: "Pricing", description: "Simple plans for growing teams.", }; - 59
Generar metadatos dinámicos
Usa generateMetadata para títulos, descripciones, URLs canónicas e imágenes sociales específicas de cada entidad. Reutiliza la función de acceso a datos de la ruta cuando sea posible.
- 60
Configura metadataBase una vez
metadataBase en la raíz permite que los enlaces canónicos y campos de imagen usen rutas relativas mientras Next.js resuelve URLs absolutas.
metadataBase: new URL("https://example.com") - 61
Generar un mapa de sitio
app/sitemap.ts devuelve URLs públicas y los campos opcionales lastModified, changeFrequency y priority. Genéralo a partir del catálogo real de contenido; Google ignora changeFrequency y priority, así que mantén lastModified preciso en lugar de fingir actualizaciones.
- 62
Publica las reglas de robots
app/robots.ts devuelve reglas de rastreo y la ubicación del sitemap. Las reglas de robots son indicaciones de rastreo, no un control de acceso a rutas privadas.
- 63
Use imágenes optimizadas
next/image necesita dimensiones intrínsecas o un contenedor fill. Proporciona texto alt preciso y sizes adaptables; usa priority solo para imágenes realmente críticas visibles al abrir la página.
- 64
Carga fuentes con next/font
next/font aloja los archivos de fuente elegidos y reduce solicitudes externas. Limita los pesos y subconjuntos a los estilos que usa la interfaz.
- 65
Programar scripts de terceros
next/script controla cuándo carga el JavaScript externo. Elige afterInteractive o lazyOnload, salvo que la integración deba formar parte de la ruta crítica.
Seguridad y configuración
Los límites del framework reducen la exposición accidental solo si el código de la aplicación mantiene explícitas la autorización y la gestión de secretos.
- 66
Mantén los secretos en el servidor
Los valores de entorno son exclusivos del servidor salvo que su nombre empiece por NEXT_PUBLIC_. Todo valor con ese prefijo público debe considerarse visible en el navegador y fijado según el entorno de compilación.
- 67
Autoriza cada punto de entrada del servidor
Comprueba la identidad actual y sus permisos en Server Actions, Route Handlers y accesos protegidos a datos. Un botón oculto o una redirección Proxy no constituyen un límite de seguridad.
- 68
Usa Proxy para la lógica de enrutamiento de cada solicitud
Next.js 16 usa proxy.ts para reescrituras, redirecciones y comprobaciones preliminares antes de que la solicitud llegue a una ruta. Mantén también la autorización segura cerca de los datos.
- 69
Utilizar cookies de sesión seguras
Configura los atributos HTTP-only, secure, same-site, path y expiry según el diseño de la sesión. Rota e invalida sesiones mediante el sistema de autenticación.
- 70
Envía datos limitados al navegador
Convierte los registros en DTO con solo los campos que necesita la interfaz. Las APIs Taint pueden añadir defensa en profundidad, pero no sustituyen una selección cuidadosa de la salida.
Producción, depuración y despliegue
Las últimas cinco comprobaciones convierten el código del framework en un sitio operable con compilaciones reproducibles y versiones observables.
- 71
Ejecuta las comprobaciones por separado
Next.js 16 no usa next build para ejecutar el lint. Separa en CI el lint, TypeScript, las pruebas y la compilación de producción.
npm run lint npx tsc --noEmit npm test npm run build - 72
Prueba el servidor de producción
Ejecuta next build y next start localmente o en una vista previa. El comportamiento de desarrollo puede ocultar problemas de importación, caché, entorno y renderizado exclusivos de producción.
- 73
Lee el resumen de rutas de la compilación
La salida de next build identifica las rutas prerenderizadas y las renderizadas durante la solicitud. Investiga una ruta que se vuelva dinámica o crezca inesperadamente, en lugar de tratar la compilación como una simple casilla de éxito o fallo.
- 74
Expón una ruta de salud veraz
Devuelve una pequeña respuesta correcta solo cuando el proceso esté listo para recibir tráfico. Mantén fuera del cuerpo público los secretos y los detalles de dependencias.
export function GET() { return Response.json({ status: "ok" }); } - 75
Despliega el proceso normal de producción
Un despliegue estándar del servidor instala desde el archivo de bloqueo, ejecuta next build, inicia con next start, inyecta secretos del entorno de ejecución, comprueba la salud y promueve solo una versión saludable.
build_cmd: npm ci && npm run build start_cmd: npm start runtime: name: node@24 port: 3000 health_path: /api/health