Menu
Coddy logo textTech

Rutas dinámicas

Parte de la sección Esenciales de Next.js del Journey de React de Coddy — lección 8 de 47.

Un menú con cuarenta platillos no necesita cuarenta carpetas. Quieres que /menu/pizza, /menu/pasta y /menu/tiramisu sean la misma página mostrando datos diferentes.

Eso es lo que significan los corchetes en el nombre de una carpeta:

app/
    menu/
        [slug]/
            page.jsx     ->  /menu/pizza
                         ->  /menu/pasta
                         ->  /menu/anything-at-all

Una carpeta normal coincide con su propio nombre. Una carpeta con [corchetes] coincide con cualquier segmento y recuerda con qué coincidió. La palabra dentro de los corchetes es el nombre con el que la leerás: [slug] te da slug, [id] te da id.

Next le pasa ese valor a la página como una prop llamada params:

// app/menu/[slug]/page.jsx
export default async function Dish({ params }) {
    const { slug } = await params;

    return <h1>{slug}</h1>;
}

Tres cosas ocurren en ese pequeño archivo:

  • La página recibe una propiedad params. Cada página recibe una, y para una ruta dinámica contiene los segmentos coincidentes.
  • params es una Promise en Next 15, por lo que usas await con ella. Por eso el componente es async. El Capítulo 5 explica por qué las páginas pueden serlo.
  • La desestructuración extrae slug, cuyo nombre proviene directamente de la carpeta [slug].

Visita /menu/pasta y slug es "pasta". Un archivo, cada plato.

challenge icon

Desafío

Fácil

La carpeta dinámica ya está allí: app/menu/[slug]/page.jsx responde a cada URL bajo /menu. El problema es que dice pizza sin importar qué plato hayas solicitado.

  1. Haz que el componente sea async.
  2. Lee el segmento coincidente con const { slug } = await params;.
  3. Renderiza slug dentro del <h1 id="dish"> en lugar del texto fijo.

Las pruebas visitan dos platos diferentes y esperan dos encabezados diferentes.

Pruébalo tú mismo

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Esenciales de Next.js