Aller au contenu principal
Site en cours de refonte — quelques pages peuvent bouger ou évoluer.
17 avril 2026

Le “back button hijacking” devient une règle Google : va chercher le script qui te piège

Google met noir sur blanc le “back button hijacking” comme pratique sanctionnable. Voilà comment l’identifier vite, isoler le script (souvent tiers), et corriger sans casser ton business.

12 min de lecture
54 vues
réactions
Partager :
Le “back button hijacking” devient une règle Google : va chercher le script qui te piège

Tu connais ce moment où tu appuies sur “retour” et… rien ne se passe. Ou pire : tu te prends une interstitielle, un overlay “reste avec nous”, une redirection chelou, et tu dois appuyer 3 fois pour réellement quitter. Google vient d’en faire une violation explicite de ses règles anti-spam. Et dans la vraie vie, le coupable n’est pas toujours “ton” code. C’est souvent un script tiers branché pour monétiser, traquer ou pousser de la conversion.

Je te propose un article très terrain : les patterns exacts qui posent problème, une méthode d’audit rapide (mobile + DevTools), comment isoler le script fautif sans jouer au Cluedo, puis des corrections propres qui évitent de flinguer ton funnel. On parle JavaScript, History API, popstate, redirections et arbitrages UX. Pas de morale, juste du concret.

Back button hijacking : ce que Google vise vraiment (et pourquoi ça peut finir en spam action)

Le “back button hijacking”, ce n’est pas “utiliser la History API”. Ce n’est pas non plus “avoir une modale”. Ce que Google vise, c’est une mécanique trompeuse qui empêche l’utilisateur de revenir en arrière normalement, ou qui le fait atterrir sur autre chose que ce qu’il a demandé, typiquement pour capter une impression pub, forcer une action, ou piéger la navigation.

La nuance est importante, parce que beaucoup de sites modernes utilisent history.pushState pour des raisons légitimes (SPA, filtres, pagination, états d’UI partageables). Le problème commence quand tu détournes le bouton retour pour déclencher un événement marketing ou une redirection qui n’a rien à voir avec l’intention de l’utilisateur. Et le risque, côté SEO, ce n’est pas juste “mauvaise UX” : Google indique que ça rentre dans ses politiques de spam, donc tu peux te prendre une action manuelle ou un traitement algorithmique selon le contexte.

Les patterns de hijacking que je vois en audit (ceux qui déclenchent les emmerdes)

Le plus classique, c’est le pushState en boucle. Un script ajoute une entrée d’historique au chargement, puis une autre quand tu essaies de repartir, puis encore une autre. Résultat : tu appuies sur retour, tu restes “sur la même page” parce que tu navigues entre des états artificiels injectés juste pour te retenir.

Le second, très courant sur mobile, c’est l’interception de popstate pour afficher un overlay ou une interstitielle au moment où l’utilisateur tente de quitter. Exemple réel : “Attends ! -10% si tu restes”, qui se déclenche uniquement quand tu fais retour. Ça peut sembler “malin” côté conversion. C’est surtout le genre de truc qui ressemble à une arnaque, et Google le classe de plus en plus clairement dans la zone rouge.

Troisième pattern : la chaîne de redirections au retour. Tu reviens, et tu es envoyé vers une autre URL (souvent une landing, parfois un “intermediate page” qui charge des tags, parfois une page pub). C’est particulièrement toxique quand ça arrive seulement sur certains devices, ou après un délai, ou selon une source d’acquisition. Le site “a l’air normal” en QA desktop, mais il piège une partie du trafic.

Et il y a un pattern plus “sournois” : l’overlay “non-fermable” ou difficilement fermable (close minuscule, scroll bloqué, retour qui rouvre l’overlay). Là, tu n’es pas obligé de toucher à la History API pour rendre la sortie pénible. Mais en pratique, ça produit le même effet : l’utilisateur ne peut plus naviguer naturellement.

Comment le détecter vite (sans te raconter d’histoires)

Le test le plus rentable, je le fais sur mobile, en conditions “réelles” : Chrome Android ou Safari iOS, navigation depuis une source externe (Google, Discover, réseau social), puis retour. Si tu testes uniquement depuis un onglet déjà ouvert, ou en rechargeant 15 fois, tu lisses parfois le comportement. Beaucoup de scripts agressifs sont conditionnés par le referrer, la campagne, le user-agent, ou un état stocké (cookie/localStorage).

Ensuite, je passe en mode preuve. Dans Chrome, tu peux observer les événements et l’historique côté DevTools, mais le plus efficace est souvent de logger ce qui touche à l’historique. L’idée n’est pas de “corriger” avec ça, juste de capturer un diagnostic fiable : qui appelle pushState, quand, et ce qui se passe au popstate.

// À coller temporairement en console (ou dans un snippet DevTools) pour diagnostiquer.
// But : trouver qui pollue l'historique et qui intercepte le retour.
(() => {
  const origPush = history.pushState;
  const origReplace = history.replaceState;

  history.pushState = function (...args) {
    console.log('[pushState]', new URL(location.href).href, args, new Error().stack);
    return origPush.apply(this, args);
  };

  history.replaceState = function (...args) {
    console.log('[replaceState]', new URL(location.href).href, args, new Error().stack);
    return origReplace.apply(this, args);
  };

  window.addEventListener('popstate', (e) => {
    console.log('[popstate]', new URL(location.href).href, e.state);
  });
})();

Si tu vois des pushState “gratuits” au chargement, ou des rafales d’appels quand tu interagis à peine, tu tiens une piste. Et si tu vois un popstate suivi immédiatement d’une modale, d’un scroll lock, ou d’un location.href = ..., là tu es très probablement sur un hijack.

Le scénario le plus fréquent : ce n’est pas ton code, c’est un script tiers

Dans beaucoup de cas, l’équipe produit jure qu’elle n’a “rien fait”. Et c’est plausible. Les scripts qui aiment ce genre de mécanique viennent souvent de briques “business” : widgets de monétisation, interstitiels, popups, scripts d’affiliation, tag managers mal maîtrisés, A/B tests qui injectent une couche d’UI, trackers un peu trop “créatifs”.

Le problème, c’est que ces scripts arrivent parfois via un conteneur (Google Tag Manager ou autre), parfois via une régie, parfois via un partenaire. Et comme ça se charge après coup, sur certaines pages, à certains moments, tu peux passer à côté en recette. Le hijack devient un bug fantôme : “je le vois sur mon téléphone mais pas sur ton desktop”.

Mon réflexe dans ces cas-là : je pars du principe que c’est tiers jusqu’à preuve du contraire. Pas pour dédouaner le site, mais parce que c’est statistiquement ce que je vois le plus. Et surtout, parce que si Google sanctionne, le responsable final sera ton domaine, pas le vendor.

Audit express : isoler le script coupable sans tout casser

La méthode la plus rapide, c’est de désactiver ce qui est injecté et de revenir à une baseline propre. Si tu as la main sur le Tag Manager, tu peux couper temporairement les tags non essentiels sur un environnement de test (ou via un “switch” par cookie). Si tu n’as pas d’environnement, tu peux déjà faire un test brutal : bloquer les requêtes réseau de certains domaines tiers via DevTools (request blocking) et vérifier si le comportement disparaît.

Sur un site un peu chargé, je m’appuie aussi sur la timeline réseau : tu reproduis le hijack, puis tu regardes quels scripts se sont chargés juste avant l’événement. Souvent, tu repères un bundle au nom obscur, une URL de régie, ou une lib de popup. Ensuite tu confirmes avec le log pushState (ou en mettant un breakpoint sur history.pushState dans Sources).

Et oui, c’est parfois un script “légitime” installé par l’équipe, genre un outil d’A/B test qui a une feature “on exit intent”. Sauf que sa définition de “exit” inclut le bouton retour, et il fait n’importe quoi avec l’historique pour être sûr de s’afficher.

Corriger sans flinguer ton funnel : les fixes qui marchent (et ceux qui sentent la rustine)

Premier principe : arrête de jouer avec l’historique si ton seul objectif est marketing. Si tu veux afficher une offre, fais-le sur une interaction normale (scroll, délai raisonnable, clic), pas en bloquant un comportement de navigation. Le bouton retour n’est pas un emplacement pub. Quand tu le traites comme tel, tu t’achètes une sanction potentielle et tu dégrades la confiance.

Deuxième principe : si tu utilises la History API pour des raisons produit (SPA, filtres), fais-le proprement. Un état doit correspondre à une URL et à une UI cohérente. Et surtout : le retour doit ramener à l’état précédent, pas déclencher une surprise. Dans les SPA, je vois souvent un anti-pattern : pousser un état pour ouvrir une modale, puis “intercepter” le retour pour la fermer, puis repousser un état derrière. Ça peut être acceptable si c’est 100% prévisible, une fois, et que ça ne retient pas l’utilisateur. Dès que tu empiles, tu crées une nasse.

Troisième principe : si tu as un besoin “exit intent”, fais-le one-shot et honnête. Une seule fois par session, avec une fermeture simple, sans redirection automatique, et sans empêcher l’utilisateur de partir. Et si ton outil tiers ne sait pas faire ça proprement, c’est un signal : il vaut mieux perdre un peu de taux de capture que de prendre un risque SEO et de se faire détester.

Enfin, côté intégration tierce, je suis assez tranché : si un vendor touche à pushState, replaceState ou intercepte popstate pour autre chose que de la navigation fonctionnelle, je le considère comme toxique par défaut. Tu peux exiger contractuellement que ça n’arrive pas, ou bloquer le script. Et si tu dois absolument le garder, isole-le (pages limitées, déclenchement strict, monitoring), parce que ce genre de comportement a tendance à revenir “par surprise” lors d’une mise à jour du script.

Le piège classique : “on va juste faire un petit hack pour que ça marche”

Je l’ai vu plusieurs fois : quelqu’un tente de “contre-hacker” le hijack en ajoutant son propre popstate handler pour annuler l’overlay, ou en forçant un history.go(-2) pour “sauter” les états. Ça marche sur ton poste, ça casse ailleurs. Et surtout, tu restes dans le même jeu débile : manipuler le retour au lieu de revenir à un comportement normal.

Le fix robuste, c’est presque toujours de supprimer la cause. Donc soit tu vires le script, soit tu changes son mode de déclenchement, soit tu le remplaces. Et si tu dois conserver une UI d’interstitiel, tu la rends non-piégeante, point. Google ne te reprochera pas d’avoir une popup en soi. Il te reprochera (et tes utilisateurs aussi) de les empêcher de naviguer.

“Prouver” que c’est réglé : QA + monitoring pour éviter la rechute

Une fois corrigé, ne t’arrête pas au “ça a l’air ok”. Documente un protocole de repro simple que n’importe qui peut refaire : device, navigateur, page d’entrée, action “retour”, résultat attendu. C’est bête, mais c’est ce qui évite que le bug revienne six semaines plus tard via un nouveau tag.

Je conseille aussi de mettre un garde-fou technique léger : en dev/staging, tu peux alerter si un script inconnu appelle history.pushState trop souvent, ou si un handler popstate déclenche une redirection. Pas besoin d’un système énorme. L’idée, c’est d’attraper le “tiens, on a ajouté un nouveau tag qui tripote l’historique” avant que ça parte en prod.

// Exemple simple de garde-fou en staging : alerte si trop de pushState.
// À activer uniquement hors prod.
(() => {
  if (location.hostname.includes('staging') === false) return;

  let count = 0;
  const origPush = history.pushState;

  history.pushState = function (...args) {
    count++;
    if (count > 5) {
      console.warn('[history] pushState suspect (>5). Vérifie les tags/tiers.', {
        url: location.href,
        stack: new Error().stack,
      });
    }
    return origPush.apply(this, args);
  };
})();

Et côté SEO, si tu as un doute sur une action manuelle, ça se regarde aussi dans Search Console. Mais mon expérience, c’est que le meilleur ROI est en amont : éviter que le comportement existe, surtout quand il vient d’un tiers qui peut changer du jour au lendemain.

Mon avis : si tu monétises en “piégeant le retour”, tu joues avec le feu

Je comprends la tentation. Tu vois un overlay au retour, tu vois un uplift sur une métrique court-termiste, tu te dis que c’est “juste un petit trick”. Sauf que tu trades de la confiance contre quelques points de conversion. Et maintenant, tu trades aussi contre un risque SEO explicite.

Si ton site dépend beaucoup du trafic organique, c’est un arbitrage franchement mauvais. Et si ton site dépend d’un réseau de scripts tiers, c’est encore pire : tu peux être “clean” dans ton repo, et te faire piéger par une mise à jour de vendor. Le bon move, c’est d’auditer maintenant, de simplifier, et de reprendre le contrôle de ce que ton navigateur fait vraiment quand l’utilisateur dit “je veux partir”.

Conclusion : reprends la main sur ton bouton retour (avant que Google ne le fasse à ta place)

Le back button hijacking, c’est le genre de pratique qui a longtemps survécu dans un angle mort, parce que c’était “caché”, conditionnel, et souvent porté par des tiers. Avec la mise à jour de Google, ça devient un sujet clair : si tu pièges la navigation, tu t’exposes.

La bonne nouvelle, c’est que c’est auditable et corrigible assez vite. Fais un test mobile sérieux, logge pushState/popstate, coupe les scripts un par un, et supprime le mécanisme au lieu de le camoufler. Après ça, ton site est plus clean, tes utilisateurs respirent, et tu dors mieux côté SEO.

Sources

Cet article vous a plu ?

Commentaires

Laisser un commentaire

Entre 10 et 2000 caractères

Les commentaires sont modérés avant publication.

Aucun commentaire pour le moment.

Soyez le premier à donner votre avis !