Adios
BlogNext.js

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.

Equipo de AdiosActualizado 17 de julio de 202622 min de lectura

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. 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. 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. 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. 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. 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. 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. 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. 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.

  1. 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>;
    }
  2. 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.

  3. 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.

  4. 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
  5. 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>;
    }
  6. 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.

  7. 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 }));
    }
  8. 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;
  9. 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();
  10. 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.

  11. 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.

  12. 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.

  1. 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.

  2. 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";
  3. 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.

  4. 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.

  5. 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.

  6. 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";
  7. 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.

  8. 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.

  9. 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.

  1. 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} />;
    }
  2. 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(),
    ]);
  3. 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.

  4. 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>
  5. 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 } }));
  6. 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;
  7. 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();
    }
  8. 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");
  9. 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");
  10. 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");
  11. 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.

  12. 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.

  1. 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
    }
  2. 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>
  3. 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.

  4. 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.

  5. 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.

  6. 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" });
    }
  7. 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));
    }
  8. 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");
  9. 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.

  1. 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.",
    };
  2. 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.

  3. 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")
  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  1. 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
  2. 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.

  3. 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.

  4. 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" });
    }
  5. 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
Todos los artículos