Segmentos de Ruta Dinámicos
Cuando no conoce los nombres exactos de los segmentos de ruta de antemano y desea crear rutas a partir de datos dinámicos, puede utilizar Segmentos Dinámicos que se completan en tiempo de solicitud o se prerrenderizan en tiempo de construcción.
Convención
Un Segmento Dinámico puede crearse envolviendo el nombre de una carpeta entre corchetes: [nombreCarpeta]
. Por ejemplo, un blog podría incluir la siguiente ruta app/blog/[slug]/page.js
donde [slug]
es el Segmento Dinámico para las entradas del blog.
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
return <div>Mi entrada: {slug}</div>
}
export default async function Page({ params }) {
const { slug } = await params
return <div>Mi entrada: {slug}</div>
}
Los Segmentos Dinámicos se pasan como prop params
a las funciones layout
, page
, route
, y generateMetadata
.
Ruta | URL de ejemplo | params |
---|---|---|
app/blog/[slug]/page.js | /blog/a | { slug: 'a' } |
app/blog/[slug]/page.js | /blog/b | { slug: 'b' } |
app/blog/[slug]/page.js | /blog/c | { slug: 'c' } |
Segmentos Comodín
Los Segmentos Dinámicos pueden extenderse para capturar todos los segmentos subsiguientes añadiendo puntos suspensivos dentro de los corchetes [...nombreCarpeta]
.
Por ejemplo, app/shop/[...slug]/page.js
coincidirá con /shop/clothes
, pero también con /shop/clothes/tops
, /shop/clothes/tops/t-shirts
, y así sucesivamente.
Ruta | URL de ejemplo | params |
---|---|---|
app/shop/[...slug]/page.js | /shop/a | { slug: ['a'] } |
app/shop/[...slug]/page.js | /shop/a/b | { slug: ['a', 'b'] } |
app/shop/[...slug]/page.js | /shop/a/b/c | { slug: ['a', 'b', 'c'] } |
Segmentos Comodín Opcionales
Los Segmentos Comodín pueden hacerse opcionales incluyendo el parámetro en dobles corchetes: [[...nombreCarpeta]]
.
Por ejemplo, app/shop/[[...slug]]/page.js
también coincidirá con /shop
, además de /shop/clothes
, /shop/clothes/tops
, /shop/clothes/tops/t-shirts
.
La diferencia entre los segmentos comodín y comodín opcionales es que con los opcionales, la ruta sin el parámetro también coincide (/shop
en el ejemplo anterior).
Ruta | URL de ejemplo | params |
---|---|---|
app/shop/[[...slug]]/page.js | /shop | { slug: undefined } |
app/shop/[[...slug]]/page.js | /shop/a | { slug: ['a'] } |
app/shop/[[...slug]]/page.js | /shop/a/b | { slug: ['a', 'b'] } |
app/shop/[[...slug]]/page.js | /shop/a/b/c | { slug: ['a', 'b', 'c'] } |
TypeScript
Cuando se utiliza TypeScript, puede añadir tipos para params
dependiendo del segmento de ruta configurado.
Ruta | Definición de Tipo para params |
---|---|
app/blog/[slug]/page.js | { slug: string } |
app/shop/[...slug]/page.js | { slug: string[] } |
app/shop/[[...slug]]/page.js | { slug?: string[] } |
app/[categoryId]/[itemId]/page.js | { categoryId: string, itemId: string } |
Comportamiento
- Dado que la prop
params
es una promesa, debe utilizarasync
/await
o la funciónuse
de React para acceder a los valores.- En la versión 14 y anteriores,
params
era una prop síncrona. Para ayudar con la compatibilidad hacia atrás, aún puede acceder a ella de forma síncrona en Next.js 15, pero este comportamiento quedará obsoleto en el futuro.
- En la versión 14 y anteriores,
Ejemplos
Con generateStaticParams
La función generateStaticParams
puede utilizarse para generar estáticamente rutas en tiempo de construcción en lugar de bajo demanda en tiempo de solicitud.
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
Cuando se utiliza fetch
dentro de la función generateStaticParams
, las solicitudes se deduplican automáticamente. Esto evita múltiples llamadas de red para los mismos datos en Layouts, Pages y otras funciones generateStaticParams
, acelerando el tiempo de construcción.