📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

~4 min de lecture

4 patterns de routing Angular pour des URLs propres et SEO-friendly

Soigner ses routes Angular, ce n'est pas que cosmétique. Une URL lisible, c'est :

  • un signal positif pour Google (mots-clés dans le chemin)
  • un meilleur taux de clic sur les partages sociaux
  • un site plus crawlable (sitemap propre, breadcrumbs cohérents)
  • une codebase plus facile à maintenir, surtout en SSR

Sur EasyAngularKit, j'utilise 4 patterns qui couvrent 95% des cas. Voici lesquels, quand les utiliser, et leurs pièges côté prerender.


TL;DR

Pattern Exemple Quand l'utiliser
1. Route dynamique simple /module/:id Listes ou détails sans contrainte de slug
2. Segment hybride /:idModule-module Tu veux à la fois lisibilité humaine et extraction d'ID
3. UrlMatcher custom /article/2024-03-:slug Format complexe avec validation
4. resolve data data: { intent: 'commercial' } Métadonnées partagées (SEO, breadcrumb, layout)

Pattern 1 — La route dynamique simple

Le pattern de base, connu de tout le monde :

export const routes: Route[] = [
  { path: 'module/:id', loadComponent: () => import('./module.page') },
];

Côté composant :

export default class ModulePage {
  private readonly route = inject(ActivatedRoute);
  protected readonly id = toSignal(this.route.paramMap.pipe(map(p => p.get('id'))));
}

Bon pour : routes de détail simples, paramètres techniques (IDs numériques, UUIDs).

Limite : l'URL ne porte aucune information sémantique. /module/3 ne dit rien sur ce que contient le module — ni à l'utilisateur, ni à Google.


Pattern 2 — Le segment hybride statique + dynamique

Le pattern méconnu d'Angular : tu peux combiner partie statique et partie dynamique dans un même segment.

export const routes: Route[] = [
  { path: ':idModule-module', loadComponent: () => import('./module.page') },
];

Tape /1-module, /2-module, /3-module — Angular match la route et extrait idModule = '1', '2', '3'.

C'est exactement ce que j'utilise pour les pages module d'EasyAngularKit. Plutôt que /module/1, l'URL devient /module-1 (segment unique), et le slug -module est implicite si on ajoute la sémantique côté template.

Variante encore plus lisible : associer un slug au paramètre.

{ path: ':id-:slug', loadComponent: () => import('./module.page') },
// matche /1-clean-architecture, /2-tests-vitest, etc.

Bon pour : URLs sémantiques avec extraction de paramètre. Excellent pour le SEO — Google indexe les mots-clés dans le path.

Piège SSR : si tu prérendres ces routes (getPrerenderParams dans app.routes.server.ts), il faut générer la liste explicite des slugs valides, sinon le crawler tombe sur un fallback 404.


Pattern 3 — UrlMatcher custom pour les formats complexes

Quand le format de l'URL doit être validé (date, slug avec contraintes, version), un UrlMatcher custom donne le contrôle total :

const dateSlugMatcher: UrlMatcher = (segments) => {
  if (segments.length !== 1) return null;
  const match = segments[0].path.match(/^(\d{4}-\d{2})-(.+)$/);
  if (!match) return null;
  return {
    consumed: segments,
    posParams: {
      yearMonth: new UrlSegment(match[1], {}),
      slug: new UrlSegment(match[2], {}),
    },
  };
};

export const routes: Route[] = [
  { matcher: dateSlugMatcher, loadComponent: () => import('./article.page') },
];

Cette route matche /2024-03-mon-article mais rejette /foo-bar. Avantages :

  • Validation au routing (pas besoin de guards séparés)
  • Paramètres typés extraits dans posParams
  • 404 propre si le format ne colle pas

Bon pour : URLs avec contraintes de format (dates, codes pays, versions). À éviter si un regex simple suffit — le code devient vite verbeux.


Pattern 4 — data resolver pour partager des métadonnées

Les routes Angular acceptent un objet data qui suit la navigation. Idéal pour propager des métadonnées partagées (intent SEO, breadcrumb, layout variant, theme).

export const routes: Route[] = [
  {
    path: 'easyangularkit',
    loadComponent: () => import('./products/eak/eak-home.page'),
    data: { product: 'eak', intent: 'commercial' },
  },
  {
    path: 'cgv',
    loadComponent: () => import('./pages/cgv/cgv.page'),
    data: { intent: 'legal', robots: 'index, follow' },
  },
  {
    path: ':slug',
    loadComponent: () => import('./blog/post.page'),
    data: { intent: 'editorial', layout: 'article' },
  },
];

Côté app.ts, on peut alors écouter le router et adapter le SEO sans toucher aux composants :

this.router.events
  .pipe(filter(e => e instanceof NavigationEnd))
  .subscribe(() => {
    const data = this.route.snapshot.firstChild?.data ?? {};
    if (data['robots']) {
      this.meta.updateTag({ name: 'robots', content: data['robots'] });
    }
  });

Bon pour : centraliser la configuration SEO, le breadcrumb, ou le layout dans les routes plutôt que dans chaque composant.

Piège : les data ne sont disponibles qu'après la navigation. Pour le SSR, on les lit dans ActivatedRouteSnapshot au server bootstrap.


Impact SEO concret

Sur EasyAngularKit, j'ai mesuré l'impact de la bascule /module/1/module-1 sur 9 pages module :

  • Sitemap plus court (1 segment au lieu de 2) → meilleure crawlabilité
  • Mots-clés dans le path (module-1, module-2, …) → signal Google explicite
  • Partage social : l'URL /module-3-clean-architecture est nettement plus engageante que /module/3

Sur les analytics : +14% de CTR organique sur les pages module en 60 jours après la bascule. Pas une preuve causale (autres optims en parallèle), mais corrélation nette.


Verdict

Pour 80% des cas : pattern 1 (route dynamique simple) suffit. Quand l'URL devient publique et que le SEO compte, bascule vers le pattern 2 (segment hybride). Le pattern 3 reste pour les cas exotiques (validation complexe). Le pattern 4 est transverse — utile dès qu'on a plus de 5 routes avec du SEO à orchestrer.

À éviter dans tous les cas : les query params pour de la navigation primaire (/products?id=3). Google les gère mal, et l'expérience utilisateur de partage est dégradée.


Tu veux maîtriser le routing Angular en profondeur ? 👉 EasyAngularKit couvre routing avancé, lazy loading et SSR dans son module dédié.

📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

AngularKit

Suite d'outils pour développeurs Angular francophones. Apprends, modernise tes réflexes, audite ta codebase.

Produits

Contact

Légal

© 2026 AngularKit. Tous droits réservés.