Published on

Maîtriser les routes dynamiques et catch-all avec Next.js

Apprenez à utiliser les routes dynamiques, la génération de paramètres statiques, et les segments catch-all dans Next.js pour construire des applications web modulaires et performantes.


Dans le développement moderne, il arrive souvent qu'on ne connaisse pas à l'avance les segments (slug) d'URL exacts. C'est ici que les routes dynamiques et les segments catch-all deviennent très puissantes.

Une approche flexible avec les routes dynamiques

Next.js permet de créer des routes dynamiques en utilisant une convention simple de nommage des fichiers :

bash
/[folderName]

Elle permet de créer des segments d'URL dynamiques. Ce segment dynamique est ensuite passé en tant que paramètre (params) aux fonctions layout, page, route et generateMetadata.

Exemple de route dynamique

Prenons l'exemple d'un blog avec des articles :

bash
/blog/[slug]/page.tsx
tsx
export default function Page({ params }: { params: { slug: string } }) {
    console.log(params);
    return <BlogArticle slug={params.slug} />;
}

Résultat de la navigation

RouteExemple d'URLparams
/blog/[slug]/page.tsx/blog/first-post{ slug: 'first-post' }
/blog/[slug]/page.tsx/blog/second-post{ slug: 'second-post' }
/blog/[slug]/page.tsx/blog/third-post{ slug: 'third-post' }

Ce simple exemple montre comment les routes dynamiques peuvent être utilisées pour créer des pages personnalisées sans avoir à créer une structure de dossiers complexe pour chaque article, ce qui peut rendre le projet plus difficile à gérer.

Optimiser avec la génération de paramètres statiques

Next.js permet également d'optimiser ces routes dynamiques en générant des paramètres statiques (static params) à partir de données dynamiques grâce à la fonction generateStaticParams. Cela permet d'améliorer les performances de l'application en générant ces pages lors du build.

Exemple de génération de paramètres statiques

tsx
import { SelectWeek } from '@/types/SelectWeek';
 
export async function generateStaticParams(): Promise<{id: string}[]> {
    const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/selection`);
    const products: SelectWeek[] = await response.json();
 
    return products.map((product) => ({
        id: product.id,
    }));
}

Résultat du build

bash
Route (app)                              
 /                                          
 /contact                             
 /login                                     
 /produit/[id]                        
 /produit/66c9813b456ad650ec0e1b32
 /produit/66c980cc456ad650ec0e1b2e
 /produit/66c9805f456ad650ec0e1b2a
 [+7 more paths]
 /robots.txt                                  
 /sitemap.xml    
 
  (Static)   prerendered as static content
  (SSG)      prerendered as static HTML (uses getStaticProps)
ƒ  (Dynamic)  server-rendered on demand

Comme on peut le voir, les routes comme /produit/[id] sont générées statiquement (●) lors du build. Le SSG (Static Site Generation) permet de précharger ces pages sur le navigateur, améliorant ainsi la vitesse de chargement et le SEO de votre application.

Bonnes pratiques

  • Utilisez generateStaticParams pour générer des paramètres statiques à partir de données dynamiques.
  • Combiner routes dynamiques et SSG permet de créer des pages statiques performantes tout en gardant une flexibilité.

Gérer des cas complexes avec les segments catch-all

Pour des cas d'utilisation plus complexes, Next.js introduit les segments catch-all via la convention [...folderName]. Ce type de segment permet de capturer tous les sous-segments d'une URL, ce qui est très utile pour des applications comme les sites e-commerce.

Exemple de route catch-all

Considérons un site e-commerce où l'utilisateur peut filtrer les produits par catégorie, sous-catégorie, taille et couleur.

tsx
export default function Page({params}: {params: {slug: string[]}}) {
    const slugSegments = params.slug
 
    const category = slugSegments[0] || 'all'
    const subcategory = slugSegments[1] || 'all'
    const size = slugSegments.find((segment) => segment.startsWith('size-'))?.split('-')[1]
    const color = slugSegments.find((segment) => segment.startsWith('color-'))?.split('-')[1]
 
    const products = await getProducts(category, subcategory, size, color)
 
    return <ProductsPage products={products} />
}

Exemple de l'URL

bash
http://localhost:3000/products/men/shirts/size-l/color-blue

Résultat de la recherche

Résultat de la recherche

L'exemple ci-dessus montre comment une seule page dynamique peut gérer un ensemble complexe de filtres en utilisant des segments catch-all, simplifiant ainsi la gestion des routes et réduisant le code redondant.

Conclusion

Les segments catch-all et les routes dynamiques de Next.js permettent non seulement de simplifier la structure des projets, mais aussi d'améliorer la developer experience (DX), la maintenabilité et l'extensibilité du code. En utilisant ces fonctionnalités, vous pouvez créer des applications modulaires et performantes.

Bon à savoir

  • Les catch-all segments peuvent être rendu facultatif en doublant les crochets [[…folderName]].