DevToolBoxGRATUIT
Blog

Cheat Sheet redirections .htaccess : Exemples à copier-coller

10 min de lecturepar DevToolBox

Le fichier .htaccess est l'un des outils de configuration les plus puissants pour les serveurs web Apache. Il vous permet de contrôler les redirections, forcer le HTTPS, définir des en-têtes de sécurité, gérer le cache et bien plus encore, sans toucher à la configuration principale du serveur. Ce guide complet .htaccess fournit des exemples prêts pour la production que vous pouvez copier et coller directement.

Redirections de base

Les redirections sont l'utilisation la plus courante des fichiers .htaccess. Que vous déplaciez une seule page, restructuriez un répertoire entier ou migriez vers un nouveau domaine, les directives Redirect et RewriteRule d'Apache le rendent simple. Utilisez toujours des redirections 301 (permanentes) pour le SEO afin de transférer la valeur des liens vers la nouvelle URL.

Rediriger une URL unique

# Redirect a single URL (301 permanent)
Redirect 301 /old-page.html https://example.com/new-page.html

# Using RewriteRule for more control
RewriteEngine On
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]

# Redirect with pattern matching (e.g., old product URLs)
RewriteRule ^products/([0-9]+)\.html$ /shop/item/$1 [R=301,L]

Rediriger un répertoire entier

# Redirect entire directory to new location
RedirectMatch 301 ^/blog/(.*)$ https://example.com/articles/$1

# Using RewriteRule (preserves subdirectory structure)
RewriteEngine On
RewriteRule ^blog/(.*)$ /articles/$1 [R=301,L]

# Redirect directory but keep filenames
RewriteRule ^old-folder/(.+)$ /new-folder/$1 [R=301,L]

Redirection de domaine à domaine

# Redirect entire old domain to new domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]

# Redirect specific domain alias to primary domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain\.net$ [NC,OR]
RewriteCond %{HTTP_HOST} ^olddomain\.org$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]

Forçage HTTPS

Forcer le HTTPS est essentiel pour la sécurité et le SEO. Google utilise le HTTPS comme signal de classement, et les navigateurs modernes avertissent les utilisateurs des connexions HTTP non sécurisées. Ces règles utilisent mod_rewrite pour rediriger tout le trafic HTTP vers HTTPS.

HTTP vers HTTPS (sans www)

# Force HTTPS (redirect HTTP to HTTPS, non-www)
RewriteEngine On

# Redirect www to non-www
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

HTTP vers HTTPS (avec www)

# Force HTTPS with www prefix
RewriteEngine On

# Redirect non-www to www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

Forcer non-www avec HTTPS

# Force non-www + HTTPS in a single pass
# Works on shared hosting and most Apache setups
RewriteEngine On

# Handle both www removal and HTTPS enforcement together
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Alternative: Using environment variables (some hosts)
# RewriteCond %{ENV:HTTPS} !on
# RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Gestion du slash final

Des slashs finaux incohérents créent des problèmes de contenu dupliqué qui nuisent au SEO. Les moteurs de recherche traitent /about et /about/ comme des URL différentes. Choisissez un style et appliquez-le de manière cohérente sur l'ensemble de votre site.

Ajouter le slash final

# Add trailing slash to all URLs (except files with extensions)
RewriteEngine On

# Only apply to URLs without a file extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.[a-zA-Z0-9]{1,5}$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]

# Simpler version (may cause issues with some file types)
# RewriteRule ^(.*[^/])$ $1/ [R=301,L]

Supprimer le slash final

# Remove trailing slash from all URLs (except directories)
RewriteEngine On

# Do not remove trailing slash from actual directories
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]

# Remove trailing slash except for root URL
# RewriteCond %{REQUEST_URI} !^/$
# RewriteRule ^(.*)/$ /$1 [R=301,L]

Gestion des chaînes de requête

La redirection d'URL avec des chaînes de requête nécessite une attention particulière. Par défaut, Apache ajoute la chaîne de requête originale à la cible. Utilisez les drapeaux QSA et ? pour conserver, supprimer ou modifier les paramètres.

Redirection en conservant la chaîne de requête

# Redirect preserving the original query string (default behavior)
# /search?q=test -> /find?q=test
RewriteEngine On
RewriteRule ^search$ /find [R=301,L]

# Redirect and APPEND additional query parameters (QSA flag)
# /page?id=5 -> /new-page?id=5&ref=old
RewriteRule ^page$ /new-page?ref=old [R=301,L,QSA]

# Match specific query string and redirect
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^product\.php$ /products/%1? [R=301,L]

Redirection en supprimant la chaîne de requête

# Redirect and DISCARD all query parameters
# /old-page?any=params -> /new-page (clean URL)
RewriteEngine On
RewriteRule ^old-page$ /new-page? [R=301,L]
# The trailing ? strips the query string

# Discard specific query parameters only
# /page?utm_source=x&id=5 -> /page?id=5 (strip tracking params)
RewriteCond %{QUERY_STRING} (^|&)utm_[^&]*
RewriteRule ^(.*)$ /$1? [R=301,L]

Redirection en modifiant les paramètres

# Rewrite query parameter to path segment
# /index.php?page=about -> /about
RewriteEngine On
RewriteCond %{QUERY_STRING} ^page=(.+)$
RewriteRule ^index\.php$ /%1? [R=301,L]

# Rewrite path segment to query parameter
# /category/electronics -> /shop.php?cat=electronics
RewriteRule ^category/([a-zA-Z0-9-]+)$ /shop.php?cat=$1 [L]

# Rename a query parameter
# /search?q=test -> /search?query=test
RewriteCond %{QUERY_STRING} ^q=(.+)$
RewriteRule ^search$ /search?query=%1 [R=301,L]

Pages d'erreur personnalisées

Les pages d'erreur personnalisées améliorent l'expérience utilisateur en fournissant des informations utiles. La directive ErrorDocument permet de définir des pages personnalisées pour tout code de statut HTTP.

# Custom error pages
# Place error page files in your document root

# 404 Not Found - page does not exist
ErrorDocument 404 /errors/404.html

# 403 Forbidden - access denied
ErrorDocument 403 /errors/403.html

# 500 Internal Server Error
ErrorDocument 500 /errors/500.html

# 401 Unauthorized - authentication required
ErrorDocument 401 /errors/401.html

# 503 Service Unavailable - maintenance mode
ErrorDocument 503 /errors/maintenance.html

# You can also use inline messages (not recommended for production)
# ErrorDocument 404 "Page not found. Please check the URL."

# Or redirect to an external URL
# ErrorDocument 404 https://example.com/not-found

# ── Maintenance mode (redirect all traffic to maintenance page) ──
# Uncomment during maintenance, recomment when done
# RewriteEngine On
# RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.000$  # Allow your IP
# RewriteCond %{REQUEST_URI} !/errors/maintenance.html$ [NC]
# RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg|gif|ico)$ [NC]
# RewriteRule ^(.*)$ /errors/maintenance.html [R=503,L]

En-têtes de sécurité via .htaccess

Les en-têtes de sécurité HTTP protègent votre site contre les attaques courantes comme le clickjacking, le XSS et l'injection de contenu. L'ajout via .htaccess nécessite l'activation de mod_headers.

# Security headers via .htaccess
# Requires mod_headers to be enabled: a2enmod headers

<IfModule mod_headers.c>

  # X-Frame-Options: Prevent clickjacking by blocking iframes
  # Options: DENY | SAMEORIGIN | ALLOW-FROM uri
  Header always set X-Frame-Options "SAMEORIGIN"

  # X-Content-Type-Options: Prevent MIME-type sniffing
  Header always set X-Content-Type-Options "nosniff"

  # X-XSS-Protection: Enable browser XSS filter (legacy)
  Header always set X-XSS-Protection "1; mode=block"

  # Referrer-Policy: Control referrer information
  Header always set Referrer-Policy "strict-origin-when-cross-origin"

  # Content-Security-Policy: Control resource loading
  # Customize the sources based on your site's needs
  Header always set Content-Security-Policy "default-src 'self'; \
    script-src 'self' 'unsafe-inline' https://cdn.example.com; \
    style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; \
    img-src 'self' data: https:; \
    font-src 'self' https://fonts.gstatic.com; \
    connect-src 'self' https://api.example.com; \
    frame-ancestors 'self';"

  # Strict-Transport-Security (HSTS): Force HTTPS for 2 years
  # Only add this if your site fully supports HTTPS
  Header always set Strict-Transport-Security \
    "max-age=63072000; includeSubDomains; preload"

  # Permissions-Policy: Disable unused browser features
  Header always set Permissions-Policy \
    "camera=(), microphone=(), geolocation=(), interest-cohort=()"

  # Remove X-Powered-By header (hides PHP/server version)
  Header unset X-Powered-By
  Header always unset X-Powered-By

</IfModule>

# Hide Apache version in server headers
ServerSignature Off

Règles de cache navigateur

Le cache navigateur améliore considérablement les temps de chargement pour les visiteurs réguliers. Le module mod_expires définit automatiquement les en-têtes Cache-Control et Expires.

# Browser caching with mod_expires
# Enable the module: a2enmod expires

<IfModule mod_expires.c>
  ExpiresActive On

  # Default expiration: 1 month
  ExpiresDefault "access plus 1 month"

  # HTML files: short cache (content changes frequently)
  ExpiresByType text/html "access plus 1 hour"

  # CSS and JavaScript: long cache (use fingerprinted filenames)
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"

  # Images: cache for 1 month
  ExpiresByType image/jpeg "access plus 1 month"
  ExpiresByType image/png "access plus 1 month"
  ExpiresByType image/gif "access plus 1 month"
  ExpiresByType image/webp "access plus 1 month"
  ExpiresByType image/avif "access plus 1 month"
  ExpiresByType image/svg+xml "access plus 1 month"
  ExpiresByType image/x-icon "access plus 1 year"

  # Fonts: cache for 1 year
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType application/font-woff2 "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"

  # JSON/XML data: short cache
  ExpiresByType application/json "access plus 1 hour"
  ExpiresByType application/xml "access plus 1 hour"

  # PDF and documents
  ExpiresByType application/pdf "access plus 1 month"
</IfModule>

# Alternative: Cache-Control headers with mod_headers
<IfModule mod_headers.c>
  # Immutable cache for fingerprinted assets
  <FilesMatch "\.(js|css)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>

  # Short cache for HTML
  <FilesMatch "\.html$">
    Header set Cache-Control "public, max-age=3600, must-revalidate"
  </FilesMatch>

  # No cache for dynamic content
  <FilesMatch "\.(php|cgi)$">
    Header set Cache-Control "no-store, no-cache, must-revalidate"
  </FilesMatch>
</IfModule>

Compression Gzip / Brotli

La compression réduit la taille des réponses de 60 à 90%, améliorant significativement les temps de chargement. Apache supporte Gzip (via mod_deflate) et Brotli (via mod_brotli, Apache 2.4.26+).

Compression Gzip (mod_deflate)

# Gzip compression using mod_deflate
# Enable the module: a2enmod deflate

<IfModule mod_deflate.c>
  # Compress text-based content types
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/xml
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/atom+xml
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/json
  AddOutputFilterByType DEFLATE application/ld+json
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE font/woff
  AddOutputFilterByType DEFLATE font/woff2
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon

  # Do not compress images (already compressed)
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|avif)$ no-gzip

  # Handle browser quirks
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

  # Add Vary header for proper caching
  Header append Vary Accept-Encoding
</IfModule>

Compression Brotli (mod_brotli)

# Brotli compression using mod_brotli (Apache 2.4.26+)
# Enable the module: a2enmod brotli

<IfModule mod_brotli.c>
  # Compress text-based content types with Brotli
  AddOutputFilterByType BROTLI_COMPRESS text/plain
  AddOutputFilterByType BROTLI_COMPRESS text/html
  AddOutputFilterByType BROTLI_COMPRESS text/xml
  AddOutputFilterByType BROTLI_COMPRESS text/css
  AddOutputFilterByType BROTLI_COMPRESS text/javascript
  AddOutputFilterByType BROTLI_COMPRESS application/xml
  AddOutputFilterByType BROTLI_COMPRESS application/xhtml+xml
  AddOutputFilterByType BROTLI_COMPRESS application/javascript
  AddOutputFilterByType BROTLI_COMPRESS application/json
  AddOutputFilterByType BROTLI_COMPRESS application/ld+json
  AddOutputFilterByType BROTLI_COMPRESS font/opentype
  AddOutputFilterByType BROTLI_COMPRESS font/ttf
  AddOutputFilterByType BROTLI_COMPRESS font/woff
  AddOutputFilterByType BROTLI_COMPRESS font/woff2
  AddOutputFilterByType BROTLI_COMPRESS image/svg+xml

  # Brotli compression quality (0-11, default: 11)
  # Lower = faster compression, larger files
  # Higher = slower compression, smaller files
  BrotliCompressionQuality 6

  # Brotli window size (10-24, default: 22)
  BrotliCompressionWindow 22
</IfModule>

# Fallback: Use Gzip if Brotli is not available
# Both modules can coexist; Apache serves Brotli to
# browsers that support it and Gzip to others.

Erreurs courantes et corrections

Le débogage des problèmes .htaccess peut être frustrant. Voici les erreurs les plus courantes et comment les éviter.

Boucles de redirection infinies

L'erreur la plus courante est de créer une boucle où l'URL réécrite correspond à nouveau à la même règle. Utilisez toujours RewriteCond pour vérifier l'état actuel et le drapeau [L] pour arrêter le traitement.

# BAD: Creates an infinite loop
# (The rewritten URL "/new" matches "^(.*)$" again)
RewriteRule ^(.*)$ /new/$1 [R=301]

# GOOD: Use RewriteCond to prevent the loop
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/new/ [NC]
RewriteRule ^(.*)$ /new/$1 [R=301,L]

# GOOD: Another approach - check if already redirected
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ /new/$1 [R=301,L]

Mauvais RewriteBase

RewriteBase définit le chemin URL de base pour les réécritures par répertoire. Si votre .htaccess est dans un sous-répertoire, le RewriteBase doit correspondre à ce chemin.

# If .htaccess is in the document root:
RewriteEngine On
RewriteBase /

# If .htaccess is in /blog/ subdirectory:
RewriteEngine On
RewriteBase /blog/

# If .htaccess is in /app/public/ subdirectory:
RewriteEngine On
RewriteBase /app/public/

# Common mistake: Using RewriteBase /blog when file is at root
# This causes all rewritten URLs to be prefixed with /blog

L'ordre des règles compte

Apache traite les règles de haut en bas. Si une règle générale précède une règle spécifique, elle correspondra en premier. Placez toujours les règles spécifiques avant les générales et utilisez le drapeau [L].

# BAD: General rule before specific rule
RewriteEngine On
RewriteRule ^(.*)$ /index.php?page=$1 [L]        # Catches everything!
RewriteRule ^about$ /about-us.html [R=301,L]      # Never reached!

# GOOD: Specific rules first, general rules last
RewriteEngine On
RewriteRule ^about$ /about-us.html [R=301,L]      # Specific: runs first
RewriteRule ^contact$ /contact-us.html [R=301,L]  # Specific: runs second
RewriteCond %{REQUEST_FILENAME} !-f                # Skip existing files
RewriteCond %{REQUEST_FILENAME} !-d                # Skip existing dirs
RewriteRule ^(.*)$ /index.php?page=$1 [L]          # General: fallback
ErreurCorrection
RewriteEngine On manquantAjoutez toujours "RewriteEngine On" en haut du bloc de règles
Points non échappés dans les motifsUtilisez \. au lieu de . dans les motifs regex
Oubli du drapeau [L]Ajoutez [L] pour arrêter le traitement après une correspondance
Mélange de Redirect et RewriteRuleUtilisez une seule méthode ; le mélange cause un comportement imprévisible
Test sans vider le cache du navigateurLes redirections 301 sont mises en cache ; utilisez 302 pendant les tests
Mauvaises permissions sur .htaccessDéfinissez les permissions à 644

Questions fréquemment posées

Qu'est-ce que .htaccess et où le placer ?

.htaccess est un fichier de configuration distribué pour les serveurs web Apache. Placez-le dans le répertoire racine de votre site (généralement public_html ou www). Il affecte le répertoire et tous ses sous-répertoires. Le fichier doit être nommé exactement ".htaccess" avec le point initial.

Quelle est la différence entre les redirections 301 et 302 ?

Une redirection 301 est permanente : elle indique aux moteurs de recherche de transférer la valeur des liens vers la nouvelle URL. Une 302 est temporaire : les moteurs gardent l'URL originale dans leur index. Utilisez 301 pour les déplacements permanents et 302 pour les situations temporaires. Les navigateurs mettent en cache les 301, utilisez donc 302 pendant les tests.

Pourquoi mes règles .htaccess ne fonctionnent-elles pas ?

Causes les plus courantes : 1) mod_rewrite non activé ; 2) AllowOverride réglé sur None ; 3) Permissions de fichier incorrectes (devrait être 644) ; 4) Erreurs de syntaxe (vérifiez le log d'erreurs Apache) ; 5) Le navigateur a mis en cache une redirection 301 précédente.

.htaccess fonctionne-t-il avec Nginx ?

Non, .htaccess est spécifique à Apache. Nginx ne supporte pas les fichiers .htaccess. Avec Nginx, vous devez ajouter les directives équivalentes directement dans la configuration du bloc server. Des outils en ligne existent pour convertir les règles .htaccess en syntaxe Nginx.

Comment rediriger les anciennes URL après une refonte ?

Créez une correspondance des anciennes vers les nouvelles URL. Pour les changements basés sur des motifs, utilisez RewriteRule avec des groupes de capture : RewriteRule ^blog/(.*)$ /articles/$1 [R=301,L]. Testez toujours avec curl -I pour vérifier le code de statut et la destination.

Comment .htaccess affecte-t-il les performances du site ?

Apache lit les fichiers .htaccess à chaque requête, ce qui ajoute un léger surcoût. Pour les sites à fort trafic, déplacez les règles dans la configuration principale Apache. Pour la plupart des sites, l'impact est négligeable et la commodité de .htaccess l'emporte.

Ce guide .htaccess couvre les modèles de redirection essentiels, les configurations de sécurité et les optimisations de performance. Testez toujours vos modifications avec curl avant le déploiement en production et conservez une sauvegarde de votre fichier .htaccess fonctionnel.

𝕏 Twitterin LinkedIn
Cet article vous a-t-il aidé ?

Restez informé

Recevez des astuces dev et les nouveaux outils chaque semaine.

Pas de spam. Désabonnez-vous à tout moment.

Essayez ces outils associés

.ht.htaccess GeneratorNXNginx Config Generator%20URL Encoder/Decoder🤖Robots.txt Generator

Articles connexes

Exemples de configuration Nginx : Reverse Proxy, SSL et sites statiques

Configurations Nginx prêtes pour la production : reverse proxy, SSL/TLS, fichiers statiques, load balancing.

Content Security Policy (CSP) : Guide complet du débutant à la production

Apprenez le CSP de zéro : toutes les directives, configurations courantes, reporting et déploiement.