Redirect .htaccess: scrivere un reindirizzamento 301 o 302 con Apache
Come scrivere un redirect 301 o 302 nel file .htaccess, quale direttiva scegliere (Redirect, RedirectMatch o RewriteRule) e i casi più comuni: cambio di dominio, HTTPS, home page, WordPress.
Il file .htaccess permette di reindirizzare un URL direttamente su un server Apache, senza toccare la configurazione principale. Ecco come scrivervi un redirect 301 o 302, quale direttiva scegliere (Redirect, RedirectMatch o RewriteRule) e come gestire i casi più comuni: cambio di dominio, HTTPS forzato, nuova home page e WordPress.
Prima di iniziare
Il .htaccess non è l'unico posto possibile: il vhost è più performante, un plugin del CMS più semplice da gestire. Per scegliere, leggete il nostro articolo .htaccess, vhost o plugin: dove mettere il piano di reindirizzamento?
Prerequisiti: il file .htaccess e i moduli Apache
Il file si trova nella radice del sito (la cartella che contiene la home page), oppure in una sottocartella per agire solo su quella directory. È un file nascosto: attivate la visualizzazione dei file nascosti nel client FTP o nel file manager dell'hosting. Se non esiste, create un semplice file di testo chiamato .htaccess.
Due moduli Apache svolgono questo lavoro:
- mod_alias, che fornisce le direttive
Redirect,RedirectPermanenteRedirectMatch; - mod_rewrite, che fornisce
RewriteEngine,RewriteCondeRewriteRule, per i casi condizionali.
Perché Apache lo legga, la configurazione del server deve autorizzare queste direttive (AllowOverride All, o almeno FileInfo). Con AllowOverride None il file viene ignorato. Su un hosting condiviso è quasi sempre già così. Nginx non ha il .htaccess: tutto va nel blocco server.
Redirect 301 o 302: permanente o temporaneo?
Un 301 indica che la pagina si è spostata in modo permanente: i motori di ricerca sanno che l'indirizzo è cambiato definitivamente, e Google trasferisce il suo valore SEO e i suoi link alla destinazione. Usatelo per una migrazione, un cambio di dominio o una pagina rinominata.
Un 302 indica uno spostamento temporaneo: l'indirizzo di origine resta indicizzato, perché deve tornare. Serve per una manutenzione, una promozione limitata nel tempo o un test. Un 302 lasciato per mesi finisce per essere trattato come un 301, ma è meglio essere espliciti fin dall'inizio.
Redirect e RedirectPermanent: il reindirizzamento semplice
Per mandare una pagina verso un'altra basta Redirect. La direttiva riceve il codice, il vecchio percorso (senza dominio) e l'indirizzo completo di destinazione:
Redirect 301 /vecchia-pagina.html https://www.miosito.it/nuova-pagina/
RedirectPermanent /vecchia-cartella/ https://www.miosito.it/nuova-cartella/
Redirect 302 /promo https://www.miosito.it/saldi/RedirectPermanent è una scorciatoia di Redirect 301, e RedirectTemp di Redirect 302. Attenzione: Redirect agisce su un prefisso. La seconda riga reindirizza anche /vecchia-cartella/pagina.html verso /nuova-cartella/pagina.html: comodo per un'intera directory, ma può sorprendere.
RedirectMatch: reindirizzare con un'espressione regolare
RedirectMatch funziona come Redirect, ma con un'espressione regolare. Gestisce un'intera famiglia di indirizzi in una riga, riutilizzando le parti catturate con $1, $2, ecc.:
# Vecchie pagine .php verso indirizzi senza estensione
RedirectMatch 301 ^/blog/(.*)\.php$ https://www.miosito.it/blog/$1
# Un solo URL esatto (^ e $ evitano l'effetto prefisso)
RedirectMatch 301 ^/contatti\.html$ https://www.miosito.it/contatti/RewriteRule e RewriteCond: i reindirizzamenti avanzati
Questo modulo è il più flessibile: ogni regola può dipendere da condizioni sul nome host, sul protocollo, sui parametri o su qualsiasi variabile del server. Il motore si attiva una sola volta, in cima al file, con RewriteEngine On.
RewriteEngine On
# Una pagina precisa, ignorando la query string
RewriteRule ^vecchia-pagina/?$ https://www.miosito.it/nuova-pagina/ [R=301,L,NC,QSD]
# Un URL con parametro: /prodotto.php?id=12
RewriteCond %{QUERY_STRING} ^id=12$
RewriteRule ^prodotto\.php$ https://www.miosito.it/prodotti/sedia/ [R=301,L,QSD]I flag tra parentesi quadre ne cambiano il comportamento:
R=301oR=302: il codice HTTP restituito (senzaRè una riscrittura interna invisibile al visitatore);L: ultima regola, Apache si ferma qui;NC: ignora maiuscole e minuscole;QSD: scarta la query string di origine (Apache 2.4);QSAla conserva aggiungendola.
Nel .htaccess il modello testato non inizia con una barra: si scrive ^vecchia-pagina, non ^/vecchia-pagina. È l'errore più frequente quando si copia un esempio scritto per un vhost.
Quale direttiva usare?
| Esigenza | Direttiva |
|---|---|
| Una pagina verso un'altra | Redirect 301 |
| Un'intera directory, con le sue sottopagine | Redirect 301 (effetto prefisso) |
| Una famiglia di indirizzi secondo un modello | RedirectMatch 301 |
| In base a host, protocollo o parametro | RewriteCond + RewriteRule |
| Un CMS che riscrive già i suoi URL (WordPress, PrestaShop) | RewriteRule |
Evitate di mescolare i due moduli per gli stessi indirizzi: mod_rewrite viene eseguito prima di mod_alias, qualunque sia l'ordine delle righe, con risultati difficili da prevedere. Su un sito che usa già mod_rewrite, scrivete tutto con lo stesso modulo.
Reindirizzare un intero dominio con il .htaccess
In un cambio di dominio, mettete queste righe sul vecchio sito, sotto la riga RewriteEngine On. Ogni indirizzo va verso la stessa pagina del nuovo dominio, percorso compreso:
RewriteCond %{HTTP_HOST} ^(www\.)?vecchio-dominio\.it$ [NC]
RewriteRule ^(.*)$ https://www.nuovo-dominio.it/$1 [R=301,L]Questa regola globale basta solo se i percorsi sono rimasti identici. Se gli URL sono cambiati, serve un piano di reindirizzamento pagina per pagina, posto prima di questa regola generale. Ricordate anche di rinnovare il vecchio nome di dominio: senza di esso, nessuno di questi redirect funziona più.
Forzare HTTPS (e www) nel .htaccess
Per mandare tutto il traffico HTTP verso HTTPS, e la versione senza www verso quella con www, in un solo passaggio:
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.miosito.it/$1 [R=301,L]Dietro un proxy o un CDN (Cloudflare, bilanciatore di carico), %{HTTPS} vale sempre off e la regola va in loop: testate invece l'intestazione %{HTTP:X-Forwarded-Proto}.
Cambiare la home page con il .htaccess
Perché un altro file faccia da home page non serve un redirect, ma la direttiva DirectoryIndex. Apache serve il primo file trovato nell'elenco, senza cambiare l'indirizzo mostrato:
DirectoryIndex home.html index.php index.htmlSe la home page deve davvero cambiare indirizzo (per esempio / verso /it/), limitate il redirect alla radice, con RedirectMatch 301 ^/$ https://www.miosito.it/it/. Senza ^/$, tutte le pagine andrebbero verso questa destinazione.
Redirect 301 nel .htaccess di WordPress
WordPress scrive le proprie regole tra le righe # BEGIN WordPress e # END WordPress, e le riscrive a ogni modifica dei permalink. Mettete sempre le vostre righe sopra questo blocco: sotto, WordPress intercetta la richiesta prima, e all'interno verrebbero cancellate. Un plugin nel menu di amministrazione è possibile, ma carica PHP a ogni visita.
# Redirect SEO
RewriteEngine On
RewriteRule ^vecchio-articolo/?$ https://www.miosito.it/nuovo-articolo/ [R=301,L]
# BEGIN WordPress
...
# END WordPressAnnullare un redirect senza cancellare le altre regole
- Fate una copia di backup del file .htaccess prima di ogni modifica.
- Apritelo con un editor di testo e cercate la riga del redirect (Redirect, RedirectMatch o RewriteRule, con le eventuali RewriteCond subito sopra).
- Cancellate queste righe, oppure commentatele con un # a inizio riga per conservarne traccia.
- Salvate e ricaricate il file sul server.
- Testate in navigazione privata: i browser mettono in cache un 301 e possono continuare ad applicarlo dopo la cancellazione.
Testare un redirect .htaccess
Il metodo più affidabile è leggere le intestazioni HTTP del server, senza la cache del browser. Da riga di comando, curl -I https://www.miosito.it/vecchia-pagina/ deve mostrare lo stato 301 e un'intestazione Location con il nuovo URL. Verificate anche che ci sia un solo passaggio: una catena (HTTP verso HTTPS, poi verso www, poi verso la pagina finale) rallenta i crawler e diluisce il segnale. Un errore 500 subito dopo il salvataggio indica un errore di sintassi: ripristinate il backup.
Per una migrazione di diverse centinaia di pagine, Swan genera le regole per il .htaccess o il vhost e testa automaticamente ogni vecchio indirizzo.
Swan genera il vostro piano di reindirizzamento per il .htaccess o il vhost e controlla ogni URL.
La checklist di migrazione SEO, in PDF. 20 pagine di controlli da spuntare, dalla decisione di migrare al monitoraggio dopo la messa in produzione.