Redirection .htaccess : écrire une redirection 301 ou 302 avec Apache

Comment écrire une redirection 301 ou 302 dans le .htaccess, quelle directive choisir (Redirect, RedirectMatch ou RewriteRule), et les cas courants : changement de domaine, HTTPS, page d'accueil, WordPress.

Redirection .htaccess : écrire une redirection 301 ou 302 avec Apache

Le fichier .htaccess permet de faire une redirection d'URL directement sur un serveur Apache, sans toucher à la configuration principale. Voici comment écrire un renvoi 301 ou 302 dans ce fichier, quelle directive choisir (Redirect, RedirectMatch ou RewriteRule), et les cas les plus courants : changement de domaine, passage au HTTPS, nouvelle page d'accueil ou site WordPress.

ℹ️

Avant de commencer

Ce fichier n'est pas le seul emplacement possible : le vhost du serveur est plus performant, et un plugin de CMS plus simple à maintenir. Pour choisir, lisez notre article .htaccess, vhost ou plugin : où placer son plan de redirection ?

Prérequis : le fichier .htaccess et les modules Apache

Le fichier se place à la racine du site (le dossier qui contient la page d'accueil), ou dans un sous-dossier pour n'agir que sur ce répertoire. C'est un fichier caché : activez l'affichage des fichiers cachés dans votre client FTP ou le gestionnaire de fichiers de votre hébergement. S'il n'existe pas, créez un simple fichier texte nommé .htaccess.

Deux modules Apache font ce travail :

  • mod_alias, qui fournit les directives Redirect, RedirectPermanent et RedirectMatch ;
  • mod_rewrite, qui fournit RewriteEngine, RewriteCond et RewriteRule, pour les cas conditionnels.

Pour qu'Apache le lise, la configuration du serveur doit autoriser ces directives (AllowOverride All, ou au moins FileInfo). Avec AllowOverride None, le fichier est ignoré. Sur un hébergement mutualisé, c'est presque toujours déjà le cas. Sous Nginx, ce fichier n'existe pas : tout s'écrit dans le bloc server de la configuration.

Redirection 301 ou 302 : permanente ou temporaire ?

Le code 301 signale un déplacement permanent : les moteurs de recherche savent que la page a définitivement changé d'adresse, et Google transfère sa valeur de référencement et ses liens vers la destination. C'est le code à utiliser pour une migration, un changement de domaine ou une page renommée.

Le code 302 signale un déplacement temporaire : l'adresse d'origine reste indexée, car elle doit revenir. Il sert pour une maintenance, une promotion limitée dans le temps ou un test. Une 302 laissée en place pendant des mois finit par être traitée comme une 301, mais il vaut mieux être explicite dès le départ.

Redirect et RedirectPermanent : la redirection simple

Pour envoyer une page vers une autre, la directive Redirect suffit. Elle prend le code, l'ancien chemin (sans le domaine) et l'adresse complète de destination :

Redirect 301 /ancienne-page.html https://www.monsite.fr/nouvelle-page/
RedirectPermanent /ancien-dossier/ https://www.monsite.fr/nouveau-dossier/
Redirect 302 /promo https://www.monsite.fr/soldes/

RedirectPermanent est un raccourci de Redirect 301, et RedirectTemp de Redirect 302. Attention : Redirect agit sur le préfixe. La deuxième ligne envoie aussi /ancien-dossier/page.html vers /nouveau-dossier/page.html, ce qui est pratique pour un répertoire entier, mais peut surprendre.

RedirectMatch : rediriger avec une expression régulière

RedirectMatch fonctionne comme Redirect, mais avec une expression régulière. Elle traite toute une famille d'adresses en une seule ligne, en réutilisant les parties capturées avec $1, $2, etc. :

# Les anciennes pages .php vers des adresses sans extension
RedirectMatch 301 ^/blog/(.*)\.php$ https://www.monsite.fr/blog/$1

# Une seule URL exacte (le ^ et le $ évitent l'effet préfixe)
RedirectMatch 301 ^/contact\.html$ https://www.monsite.fr/contact/

RewriteRule et RewriteCond : les redirections avancées

Ce module est le plus puissant : chaque règle peut dépendre de conditions sur le nom d'hôte, le protocole, les paramètres ou n'importe quelle variable du serveur. Le moteur s'active une seule fois, en haut du fichier, avec RewriteEngine On.

RewriteEngine On

# Une page précise, en ignorant la chaîne de requête
RewriteRule ^ancienne-page/?$ https://www.monsite.fr/nouvelle-page/ [R=301,L,NC,QSD]

# Une URL avec paramètre : /produit.php?id=12
RewriteCond %{QUERY_STRING} ^id=12$
RewriteRule ^produit\.php$ https://www.monsite.fr/produits/chaise/ [R=301,L,QSD]

Les drapeaux entre crochets changent son comportement :

  • R=301 ou R=302 : le code HTTP renvoyé (sans R, c'est une réécriture interne invisible pour le visiteur) ;
  • L : dernière règle appliquée, Apache s'arrête là ;
  • NC : ne tient pas compte des majuscules ;
  • QSD : supprime la chaîne de requête d'origine (Apache 2.4) ; QSA la conserve en l'ajoutant.

Dans ce fichier, le motif testé ne commence pas par une barre oblique : on écrit ^ancienne-page, et non ^/ancienne-page. C'est l'erreur la plus fréquente quand on copie un exemple écrit pour un vhost.

Quelle directive utiliser ?

BesoinDirective
Une page vers une autreRedirect 301
Un répertoire entier, avec ses sous-pagesRedirect 301 (effet préfixe)
Une famille d'adresses selon un motifRedirectMatch 301
Selon le nom d'hôte, le protocole ou un paramètreRewriteCond + RewriteRule
Un CMS qui réécrit déjà ses URL (WordPress, PrestaShop)RewriteRule

Évitez de mélanger les deux modules pour les mêmes adresses : mod_rewrite s'exécute avant mod_alias, quel que soit l'ordre des lignes, ce qui donne des résultats difficiles à prévoir et des erreurs en masse. Sur un site qui l'utilise déjà, écrivez tout avec le même module.

Rediriger un nom de domaine entier avec le .htaccess

Lors d'un changement de nom, placez ce fichier sur l'ancien site, sous la ligne RewriteEngine On. Chaque adresse est envoyée vers la même page du nouveau site, chemin compris :

RewriteCond %{HTTP_HOST} ^(www\.)?ancien-domaine\.fr$ [NC]
RewriteRule ^(.*)$ https://www.nouveau-domaine.fr/$1 [R=301,L]

Cette règle globale ne suffit que si les chemins sont restés identiques. Si les urls ont changé, il faut un plan de redirection page par page, placé avant cette règle générale. Pensez aussi à renouveler l'ancien nom de domaine : sans lui, plus aucune de ces redirections ne fonctionne.

Forcer le HTTPS (et le www) dans le .htaccess

Pour envoyer tout le trafic HTTP vers HTTPS, et la version sans www vers la version avec www, en un seul saut :

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.monsite.fr/$1 [R=301,L]

Derrière un proxy ou un CDN (Cloudflare, répartiteur de charge), %{HTTPS} vaut toujours off et la règle tourne en boucle : testez plutôt l'en-tête %{HTTP:X-Forwarded-Proto}.

Changer la page d'accueil avec le .htaccess

Pour qu'un autre fichier serve d'accueil, il ne faut pas un renvoi mais la directive DirectoryIndex. Apache sert le premier fichier trouvé dans la liste, sans changer l'adresse affichée :

DirectoryIndex accueil.html index.php index.html

Si l'accueil doit vraiment changer d'adresse (par exemple / vers /fr/), limitez le renvoi à la racine, avec RedirectMatch 301 ^/$ https://www.monsite.fr/fr/. Sans le ^/$, tout le site partirait vers cette destination.

Redirection 301 dans le .htaccess de WordPress

WordPress écrit ses propres règles entre les lignes # BEGIN WordPress et # END WordPress, et les réécrit à chaque changement des permaliens. Placez toujours vos propres lignes au-dessus de ce bloc : en dessous, le système de WordPress capte la demande avant elles, et à l'intérieur, elles seraient effacées. Un plugin de gestion des redirects dans le menu de l'administration reste possible, mais il charge PHP à chaque visite.

# Redirections SEO
RewriteEngine On
RewriteRule ^ancien-article/?$ https://www.monsite.fr/nouvel-article/ [R=301,L]

# BEGIN WordPress
...
# END WordPress

Annuler une redirection sans supprimer les autres règles

  1. Faites une copie de sauvegarde du fichier .htaccess avant toute modification.
  2. Ouvrez-le avec un éditeur de texte et cherchez la ligne de la redirection (Redirect, RedirectMatch ou RewriteRule, avec ses RewriteCond éventuelles juste au-dessus).
  3. Supprimez ces lignes, ou commentez-les en ajoutant un # en début de ligne pour garder une trace.
  4. Enregistrez et renvoyez le fichier sur le serveur.
  5. Testez en navigation privée : une redirection 301 est mise en cache par le navigateur, qui peut continuer à l'appliquer après sa suppression.

Tester une redirection .htaccess

Le plus fiable est de lire les en-têtes HTTP renvoyés par le serveur, sans le cache du navigateur. En ligne de commande : curl -I https://www.monsite.fr/ancienne-page/ doit afficher le code 301 et l'en-tête Location avec la nouvelle URL. Vérifiez aussi qu'il n'y a qu'un seul saut : une chaîne (HTTP vers HTTPS, puis vers www, puis vers la page finale) ralentit les robots et dilue le signal. Une erreur 500 juste après l'enregistrement signale une faute de syntaxe dans le fichier : restaurez la sauvegarde.

Pour une migration de plusieurs centaines de pages, Swan génère les règles pour ce fichier ou pour le vhost, et teste automatiquement chaque ancienne adresse.

<p><code>Redirect</code> (mod_alias) envoie un chemin vers une adresse, simplement. <code>RewriteRule</code> (mod_rewrite) accepte des expressions régulières et des conditions sur le domaine, le protocole ou les paramètres. Pour une seule page, <code>Redirect 301</code> suffit.</p>
<p>Les causes les plus fréquentes : un serveur qui ignore le fichier, une barre oblique en trop au début du motif d'une <code>RewriteRule</code>, une règle placée sous le bloc WordPress, ou une ancienne 301 gardée en cache par le navigateur.</p>
<p>Il n'y a pas de limite technique, mais Apache relit tout le fichier à chaque requête. Au-delà de quelques milliers de lignes, placez plutôt le plan dans le vhost.</p>

Swan génère votre plan de redirection pour le .htaccess ou le vhost, et vérifie chaque URL.

La checklist de migration SEO, en PDF. 20 pages de contrôles à cocher, de la décision de migrer au suivi après la bascule.

À lire ensuite

Tous les articles