Shallow Routing : Naviguer vite et bien sans recharger la page

Le shallow routing permet de changer d'URL sans perdre l'état de l'interface, pour des expériences plus rapides, plus fluides, et plus SEO-friendly. Dans cet article, on explore ce concept en profondeur, ses pièges, ses cas d’usage...

Illustration d'un utilisateur qui navigue entre onglets et modales flottantes, tandis que l’arrière-plan reste stable pour symboliser la conservation de l’état

Dans un web toujours plus interactif, les utilisateurs attendent des applications rapides, réactives et sans friction. Quand on change d'onglet, filtre un tableau ou ouvre une modale, l'expérience ne devrait pas se dégrader, ni provoquer un flash d'attente ou une perte d'état.

C'est dans ce contexte que le shallow routing s'impose comme un outil précieux. Encore méconnu, il permet de changer d'URL sans recharger la page, tout en conservant l'état de l'interface. Un détail ? Pas vraiment. Bien utilisé, c'est un levier de performance, d'UX et même de SEO technique.

Qu'est-ce que le shallow routing ?

Le shallow routing consiste à modifier l'URL visible dans la barre d'adresse du navigateur sans recharger la page ni relancer la logique de chargement globale de l'application.

Concrètement, cela s'appuie sur les méthodes history.pushState() ou history.replaceState() du navigateur. Cela permet d'indiquer une nouvelle URL au navigateur, sans déclencher une requête réseau ni détruire la structure actuelle de la page.

Cela s'oppose au routing classique, où chaque changement d'URL déclenche généralement un nouveau rendu complet de la page, voire une nouvelle requête vers le serveur.

Différence de comportement

Aspect Routing Classique Shallow Routing
Chargement de page Rechargement complet (requête réseau ou nouveau rendu) Pas de rechargement, interface conservée
Modification de l'URL Oui, via navigation standard Oui, via pushState / replaceState
Conservation de l'état Non, tout est réinitialisé Oui, l'état reste intact
Performance Moins performant Plus fluide, instantané

Pourquoi utiliser le shallow routing ?

Voici les bénéfices clés du shallow routing, tant pour les développeurs que pour les profils orientés UX ou marketing technique.

  1. Des performances accruesEn évitant les appels réseau ou les rechargements d'interface inutiles, le shallow routing rend l'interaction quasi-instantanée.
  2. Une meilleure expérience utilisateurPas d'écran blanc, pas d'interruption de scroll ou de formulaire : la navigation semble naturelle, sans rupture.
  3. Des URLs dynamiques et partageables : Le shallow routing permet d'exprimer l'état de l'application dans l'URL (?tab=profil?photo=42...), sans pour autant déclencher de rerender. Idéal pour le tracking, le partage de lien, ou la navigation entre onglets ou vues modales.
  4. Une gestion fine de l'état : Plutôt que de stocker l'état de l'interface uniquement en mémoire, on peut le refléter dans l'URL. Cela permet notamment de synchroniser les filtres, le tri, ou même une modale ouverte.

À lire aussi :

Les pièges fréquents à éviter

Même si le shallow routing est puissant, il demande un minimum de rigueur côté développement.

  1. Gestion explicite du bouton "Retour" et "Suivant" : Puisque vous manipulez manuellement l'historique, il faut penser à écouter les événements popstate et enregistrer un state clair dans pushState. Sinon, impossible de savoir si on était dans une modale ou sur une page complète après retour ou avancée.
  2. Synchronisation manuelle de l'interface : Changer l'URL n'est qu'une partie du travail. Vos composants doivent se mettre à jour en fonction des nouveaux paramètres. Il ne faut pas compter sur un framework ou un rafraîchissement implicite pour le faire à votre place.

Exemple complet : galerie photo avec modale

Prenons un exemple inspiré de Facebook : une galerie photo. Vous pouvez cliquer sur une image pour l'agrandir en modale sans quitter la page. Mais si vous copiez-collez l'URL, la personne qui ouvre ce lien voit la photo en pleine page, avec tout le contexte chargé normalement.
Ce pattern hybride est à la fois UX-friendly et SEO-compatible.

HTML : un lien fonctionnel sans JavaScript

<a href="/photo/42" class="photo-link" data-photo-id="42">
  <img src="/img/thumbs/42.jpg" alt="Photo 42" />
</a>

Sans JavaScript, ce lien fonctionne parfaitement : il mène à une page /photo/42 avec un rendu serveur complet.
Avec JavaScript, on peut intercepter le clic pour afficher une modale et éviter la navigation complète.

JavaScript : shallow routing avec récupération de contenu réel

document.querySelectorAll('.photo-link').forEach(link => {
  link.addEventListener('click', async (e) => {
    // Bloquage du lien naturel
    e.preventDefault();

    const photoId = link.dataset.photoId;
    const url = `/photo/${photoId}`;

    // Mise à jour de l'URL + état
    history.pushState({ modal: true, photoId }, '', url);

    // Appel de la vraie page, mais via JS
    const response = await fetch(url);

    if (response.ok) {
      const html = await response.text();
      openPhotoModal(html);
    }
  });
});

function openPhotoModal(innerHtml) {
  const modal = document.createElement('div');
  modal.className = 'modal';
  modal.innerHTML = `
    <div class="modal-content">
      ${innerHtml}
      <button id="close-modal">Fermer</button>
    </div>
  `;
  document.body.appendChild(modal);

  document.getElementById('close-modal').addEventListener('click', () => {
    modal.remove();
    history.back();
  });
}

// Gérer les boutons Précédent / Suivant
window.addEventListener('popstate', async (event) => {
  const state = event.state || {};

  if (state.modal && state.photoId) {
    const response = await fetch(`/photo/${state.photoId}`);
    const html = await response.text();
    openPhotoModal(html);
  } else {
    const modal = document.querySelector('.modal');
    if (modal) modal.remove();
  }
});

Et côté serveur ?

Vous pouvez détecter côté serveur si la requête provient de JavaScript en observant les headers comme Accept, Sec-Fetch-Mode ou d'autres signaux modernes. Cela vous permet de renvoyer une version réduite de la page (par exemple, uniquement le HTML de la modale) lors d'un fetch().

Si une même URL (/photo/42) peut renvoyer deux contenus différents (modale vs page complète), n'oubliez pas d'ajouter un header Vary, comme :

Vary: Accept, Sec-Fetch-Mode

Cela évite que les systèmes de cache retournent un contenu inadéquat à un autre type de requête.

Bonnes pratiques

Le shallow routing, bien utilisé, est un véritable levier de performance, d'UX et de compatibilité SEO. Il vous permet d'enrichir l'interface sans compromettre sa lisibilité, son accessibilité ni sa structure de navigation.
À retenir :

  • Utilisez-le pour les interactions dynamiques (modales, filtres, onglets...)
  • Gardez l'URL synchronisée avec l'état de l'interface
  • Pensez aux cas sans JavaScript : le lien doit fonctionner seul
  • Enregistrez un state explicite pour gérer retour/suivant
  • Vous pouvez appeler vos vraies pages avec un header ou détection automatique pour en extraire une version modale
  • Ne remplacez pas le routing classique : complétez-le intelligemment

Le shallow routing n'est pas là pour contourner les bonnes pratiques, il est là pour les enrichir, avec plus de finesse et plus de fluidité.

Vous travaillez sur une interface dynamique ou un site à fort enjeu SEO ? Enodo vous accompagne pour allier performance, accessibilité et impact.

  • SEO
  • Performance
  • UX
  • Bonnes pratiques
  • Code Quality
Jérôme Musialak

Jérôme Musialak

CEO @ Enodo

Développeur passionné depuis l'âge de 11 ans, Jérôme a fait ses armes chez MinuteBuzz puis en tant que CTO de MeltyGroup, où il a piloté l'infrastructure technique d'une trentaine de sites à fort trafic incluant Virgin Radio, L'Étudiant, ... et les médias du groupe. Fort de cette expérience et conscient des défis récurrents rencontrés par les entreprises pour créer et diffuser efficacement leur contenu, il fonde Enodo (du latin "dénouer les nœuds") avec pour mission de simplifier l'écosystème digital. Expert en optimisation de performance et en architecture haute disponibilité, il met son obsession du détail technique au service des enjeux business pour construire des systèmes fiables qui permettent à chacun de dormir tranquille.

Sur le même thème