Cambiare URL è facile. Il redirect decide se il passaggio funziona

Ti bastano due minuti per impostare un redirect. Verifichi nel browser e compare la pagina che volevi. Il controllo si ferma qui.

Il vecchio URL, però, resta quello che conoscono gli altri. Sta nei link pubblicati da siti che non gestisci, nelle email partite mesi fa, nei preferiti, nei feed, nei PDF che qualcuno ha scaricato, negli indici dei motori. Puoi cambiare l’indirizzo sul sito quando vuoi: quei riferimenti continueranno a chiamare il precedente, e su quasi nessuno di loro hai modo di intervenire.

Tu decidi che cosa risponde quel vecchio indirizzo quando lo chiamano. La persona che clicca un link di tre anni fa e il crawler che ripassa stanotte finiscono dove li hai mandati.

Che cos’è un redirect

Un redirect, o reindirizzamento, è la risposta con cui un server dichiara che il contenuto chiesto a un certo URL si trova a un altro indirizzo. Al posto della pagina parte uno status code della famiglia 3xx, che dichiara se il cambio è definitivo o provvisorio, accompagnato dall’intestazione Location, dove è scritto l’indirizzo di arrivo. Un documento vero e proprio non c’è: al massimo il server allega due righe di cortesia che nessuno legge, perché il client tira dritto verso la destinazione.

A riceverlo è un client, che nel vocabolario di HTTP è qualunque cosa faccia una richiesta: il browser di chi sta navigando, ma insieme a lui Googlebot, i crawler che raccolgono contenuti per i motori generativi, il programma che scarica un feed, l’integrazione di un partner che interroga un tuo endpoint. Il client legge il codice, prende l’indirizzo scritto in Location e chiede quello: è la chiamata successiva a restituire la pagina. Chi naviga non se ne accorge, perché il browser lavora per conto suo e mostra soltanto l’arrivo.

Questo è il motivo per cui un redirect sbagliato non ti arriva addosso come arrivano gli altri errori. Una pagina con un refuso, un link rotto, un modulo che non invia: qualcuno li apre, li vede, te lo dice. Una risposta non la legge nessuno — la esegue, e la esegue allo stesso modo quando è giusta e quando è sbagliata, perché per HTTP la transazione è riuscita in entrambi i casi: il server ha risposto, il client ha obbedito. Non c’è niente che qualcuno abbia motivo di segnalare, e tu lo scopri solo se vai a guardare.

Attiva una prova di SEOZoom e scopri cosa dice di te l'AI

Nemmeno il tuo browser ti aiuta, perché fa esattamente quello che deve: le intestazioni precedono il documento, lui le esegue prima di disegnare qualcosa, e quando la pagina compare il codice è già passato. Apri il vecchio indirizzo, vedi la destinazione giusta, chiudi. Quello che non hai visto è con quale codice ci sei arrivato, e attraverso quanti passaggi.

Che cosa non è un redirect

Riscrittura interna, canonical, meta refresh e spostamento scritto in JavaScript vengono chiamati redirect nel parlato comune, ma nessuno dei quattro fa quello che fa una risposta 3xx. A distinguerli è il momento in cui agiscono, perché da quello dipende chi li riceve.

La riscrittura interna non sposta niente: il server consegna un altro file sotto l’URL che era stato chiesto, e a chi ha fatto la richiesta non arriva nessuna informazione nuova. Il canonical lascia entrambe le pagine raggiungibili con risposta 200 e segnala ai motori quale versione preferire, senza obbligare nessuno a cambiare indirizzo. Il meta refresh e lo spostamento affidato a uno script agiscono a documento già consegnato, quindi raggiungono soltanto chi quel documento lo interpreta o lo esegue.

Il discrimine, allora, è se il vecchio indirizzo smette di rispondere. Con la riscrittura, con il canonical e con lo spostamento dichiarato dentro il documento continua a rispondere 200 a chiunque lo chieda: la pagina è ancora servita da quell’URL, e chi non interpreta l’HTML non ha modo di sapere che volevi mandarlo altrove. Il 3xx interviene prima del documento, ed è l’unico che vale allo stesso modo per tutti i client.

Che cosa arriva davvero a chi chiama l’indirizzo
Meccanismo Che cosa arriva a chi chiama Chi lo riceve A che cosa serve
Redirect 3xx una risposta al posto del documento, con la destinazione chiunque faccia la chiamata spostare un URL
Riscrittura interna (RewriteRule senza [R]) la pagina, sotto l’URL che era stato chiesto resta dentro il server consegnare un altro file mantenendo l’indirizzo
rel="canonical" la pagina, con un’indicazione nel documento, ed entrambe le versioni a 200 i motori di ricerca, come preferenza indicare quale versione consolidare
meta refresh e JavaScript la pagina intera, e lo spostamento dopo la consegna chi interpreta l’HTML o esegue il codice casi residui, quando il server non può rispondere prima

L’ultima riga oggi ti costa più di ieri. I crawler dei motori generativi scaricano il documento e il codice non lo eseguono — il meccanismo, con i numeri, sta nella nostra guida alla SEO tecnica — e un redirect scritto in JavaScript per loro non esiste: il vecchio URL resta quello buono e la pagina nuova non è mai stata pubblicata.

Quali sono i tipi di redirect

Il numero che scrivi dichiara qualcosa sul futuro di quell’indirizzo, e continua a dichiararlo a chiunque chiami, anche quando tu hai cambiato idea. I codici disponibili appartengono tutti alla famiglia 3xx, e dicono cose diverse.

Il 301 dichiara che l’indirizzo non tornerà. Il 302 dichiara il contrario: la deviazione è momentanea e l’originale resta valido. Google tratta il 301 come segnale forte di canonicalizzazione — cioè come indicazione che il nuovo URL prende il posto del vecchio — e il 302 come segnale debole.

Il 307 e il 308 ripetono quelle stesse dichiarazioni, temporaneo e permanente, aggiungendo una garanzia sul modo in cui la richiesta arriva a destinazione. Per Google il 308 equivale al 301 e il 307 al 302. Resta fuori il 303, che manda a una risorsa diversa da quella chiesta e sulla durata non dichiara niente.

I cinque codici 3xx per quello che ciascuno dichiara
Codice Che cosa dichiara Metodo conservato In cache senza scadenza Per Google
301 spostamento permanente no segnale forte
302 spostamento temporaneo no no segnale debole
303 risorsa diversa, nessuna durata no no
307 spostamento temporaneo no come il 302
308 spostamento permanente come il 301

Nella stessa famiglia c’è anche il 304, che però non sposta nessuno: dice al client che la copia già in suo possesso è ancora valida.

Differenza tra 301 e 302

La scelta si presenta ogni volta che un indirizzo cambia e viene risolta con quello che sembra il codice più sicuro: nel dubbio 301, che suona definitivo. È il ragionamento sbagliato, perché confonde la sicurezza che hai sul passato — quella pagina l’ho spostata — con quella che hai sul futuro, che è l’unica cosa di cui parla il codice.

Permanente e temporaneo, però, non sono simmetrici, e l’asimmetria non riguarda il giorno in cui scrivi la regola, ma quello in cui devi correggerla. La RFC 9110 stabilisce che il 301 e il 308 possono essere memorizzati in cache anche senza una scadenza esplicita, mentre il 302, il 303 e il 307 no. Un 301 che hai pubblicato per sbaglio continua quindi a mandare dove avevi detto anche dopo che l’hai corretto, perché i client che l’avevano già ricevuto non tornano a chiedere niente al tuo server: la correzione, semplicemente, non li raggiunge. Devono essere loro a svuotare quello che hanno in memoria, e quando succede lo decidono loro.

Un 302 sbagliato, invece, lo correggi e la modifica vale dalla chiamata successiva. Quando il futuro di quell’indirizzo non lo conosci davvero, il codice prudente è il temporaneo — l’opposto di quello che detta l’istinto.

307 e 308, i codici che conservano il metodo

La RFC 9110 annota, sia al 301 sia al 302, che per ragioni storiche un client può cambiare il metodo della richiesta da POST a GET. È un’eredità di come i browser si comportavano trent’anni fa, ed è rimasta nella specifica perché cambiarla avrebbe rotto quello che nel frattempo era stato costruito sopra.

Sul tuo sito significa questo: se sposti l’indirizzo a cui un modulo invia i dati e lo fai con un 301, il modulo arriva a destinazione senza i dati che conteneva. Chi ha compilato vede la pagina di conferma, perché la conferma viene servita comunque, e tu non ricevi niente. Non c’è nessun errore da nessuna parte e tutte le risposte in gioco sono formalmente corrette, quindi nessun controllo tecnico lo segnala: il guasto si misura sugli invii che non arrivano.

Il 307 e il 308 conservano il metodo, ed è l’unica ragione per cui esistono. Su un endpoint che riceve dati sono i codici da usare, e sono anche i due che nessuno guarda, perché i moduli non stanno nella mappa degli URL di un sito.

I link che puntano al vecchio indirizzo

Un indirizzo che sta online da anni ha ricevuto link da altri siti, e quei link restano dove sono: non li puoi rifare e non li puoi correggere. La domanda che viene subito dopo è se continuano a valere qualcosa adesso che chi li segue passa da un redirect.

La risposta di Google è sì: i redirect permanenti non causano perdita di PageRank, e il 301 è il segnale forte con cui il nuovo URL prende il posto del vecchio. Chi arriva da quel link arriva dove sarebbe arrivato, con un passaggio in più.

La dichiarazione, però, non vale da sola. Vale nel tempo del motore e non nel tuo, perché il consolidamento avviene quando il vecchio indirizzo viene riscansionato e lo spostamento viene registrato. Vale se la destinazione è pertinente, perché molti URL mandati su una pagina che non c’entra vengono trattati come soft 404, e da un soft 404 non si consolida niente. E vale per il permanente: con un 302 il segnale resta debole e Google può continuare a considerare canonico il vecchio indirizzo, che poi è esattamente quello che quel codice gli sta dichiarando.

Scrivere la regola giusta, quindi, non basta. Il codice dice al motore che cosa è successo all’indirizzo; la pertinenza della destinazione decide se c’è qualcosa da consolidare. Un codice sbagliato rallenta il passaggio; una destinazione sbagliata lo annulla.

Fuori da Google questa meccanica non ha un equivalente dichiarato. Il redirect agisce sulle chiamate che arrivano dopo di lui, e quello che un sistema generativo ha già raccolto sta in un archivio che non è il tuo: non esiste un modo documentato in cui un 301 riscriva a ritroso quello che è stato preso prima. Sul vecchio indirizzo decidi che cosa troverà chi passa da domani, non che cosa ha letto chi è passato l’anno scorso.

Quei lettori automatici, poi, non sono tutti lo stesso lettore. OpenAI distingue OAI-SearchBot, che serve a comparire nelle risposte di ricerca di ChatGPT, da GPTBot, che raccoglie contenuti per l’addestramento dei modelli, e li governa con controlli robots.txt indipendenti: sono due visite con scopi diversi e tempi propri, tanto che per recepire una modifica al file la documentazione dichiara circa ventiquattro ore. Lo stesso indirizzo, lo stesso redirect, e conseguenze che maturano in momenti diversi.

Le situazioni in cui serve un redirect

Un URL che hai pubblicato smette di portare al contenuto che prometteva, e il motivo per cui smette decide il lavoro che ti aspetta. Se a muoversi è l’impianto — il dominio, il protocollo, la forma dei percorsi — le destinazioni esistono già tutte e il compito è farle combaciare una per una: è lungo, è meccanico, e lo puoi delegare a chi sa scrivere una regola. Se a muoversi è il contenuto, ogni destinazione va scelta, e quella parte non la delega nessuno, perché richiede di sapere che cosa cercava chi arrivava su quella pagina.

  • Cambi dominio. Il sito si sposta per intero e le pagine restano quelle di prima, quindi ogni vecchio percorso ha un corrispondente esatto sul dominio nuovo.
  • Passi a HTTPS. Fino a quando la vecchia versione risponde, il sito è raggiungibile su due protocolli con gli stessi contenuti, e i motori si trovano davanti due copie fra cui scegliere.
  • Cambi CMS o struttura degli URL. La piattaforma nuova riscrive la forma dei percorsi, e le pagine che avevi indicizzato rispondono a indirizzi che prima non esistevano.
  • Unisci due siti. Dopo una fusione o un’acquisizione uno dei due domini viene dismesso, e quello che aveva accumulato arriva sul dominio superstite soltanto se lo reindirizzi.
  • Ritiri una pagina. Una scheda prodotto fuori catalogo, due articoli che dicevano la stessa cosa e diventano uno, una guida sostituita dalla versione aggiornata: qui il corrispondente esatto non esiste e la scelta è tua.
  • Consolidi le varianti dello stesso contenuto. Con e senza www, con e senza slash finale, con parametri appesi che lasciano identica la pagina: senza una versione unica, link e segnali si distribuiscono su indirizzi diversi che mostrano la stessa cosa.
  • Metti una pagina in manutenzione. Lo spostamento dura quanto l’intervento, e dichiararlo provvisorio invece che definitivo cambia il codice da usare.

Ci sono poi gli indirizzi che nessuno considera parte del sito e che rispondono lo stesso: gli URL brevi di una campagna, l’endpoint di un feed, quello a cui un partner manda le chiamate. Nelle migrazioni saltano facilmente, perché non stanno nel menu e non li vede nessuno finché non smettono di funzionare.

Le alternative al redirect

Reindirizzare ha senso se esiste un contenuto che copre la stessa esigenza di quello che stai togliendo. Raggiungibile non significa pertinente: puoi mandare tutto da qualche parte, ottenere una risposta 200 per ogni vecchio indirizzo, e avere comunque spostato le persone su qualcosa che non stavano cercando. La risposta giusta dipende da che cosa è successo a quella pagina, e le possibilità sono poche.

La risposta corretta secondo quello che è successo alla pagina
Che cosa è successo Che cosa rispondere Che cosa succede se sbagli
Esiste una pagina che risponde alla stessa esigenza 301 verso quella pagina
Il contenuto è finito e non ha un sostituto 404 o 410 reindirizzando forzi chi cerca una cosa verso un’altra
Le due pagine devono restare entrambe raggiungibili rel="canonical" o noindex con un redirect ne togli una dalla circolazione
La pagina torna fra qualche ora 503 con Retry-After una pagina di cortesia servita con 200 dichiara al crawler che quel contenuto è quello definitivo
Il sito intero è irraggiungibile 503 su tutto con 5xx e 429 la scansione rallenta, e gli URL indicizzati restano per un periodo prima di essere lasciati cadere

Fra 404 e 410 la differenza è meno grande di quanto si dica, ma non sta dove la si cerca. Il 410 gode della fama di accelerare l’uscita dall’indice e non lo fa: Google tratta allo stesso modo tutti gli errori 4xx tranne il 429, e in entrambi i casi la pagina esce quando viene riscansionata, esattamente come con un 404.

Quel «quando» è la parte che decide, e non dipende da te. La riscansione di un indirizzo non segue un calendario ma la frequenza con cui quell’indirizzo viene chiesto e linkato: le pagine che qualcuno continua a chiamare tornano sotto gli occhi del crawler in giorni, quelle che non chiama più nessuno possono restare a lungo, e sono proprio quelle che nessuno sta cercando. Se il problema è togliere in fretta un contenuto dai risultati — un prezzo sbagliato, un documento pubblicato per errore — né il 404 né il 410 sono lo strumento: serve lo strumento per le rimozioni di Search Console, che blocca la visualizzazione di quell’indirizzo nei risultati per circa sei mesi mentre la deindicizzazione fa il suo corso — ed è una delle strade che abbiamo messo in fila nella guida su come rimuovere contenuti da Google.

Gli effetti della scelta fra 404 e 410 si vedono altrove, e su un sito grande sono concreti. Il 410 dichiara che la rimozione è voluta, il 404 lascia aperta l’ipotesi del guasto: nel monitoraggio significa che i 410 si possono archiviare, mentre ogni 404 va guardato per capire se è una rimozione o un guasto. Su un catalogo dove ogni mese escono e rientrano centinaia di schede, è la differenza fra un rapporto che qualcuno legge e un elenco di errori che nessuno apre più.

Il 503 invece vive di una variabile sola, la durata. Dichiara che la pagina non è disponibile adesso e che vale la pena ripassare, e con Retry-After puoi dire quando: finché l’indisponibilità dura ore o giorni è la risposta corretta e non costa niente. Se dura settimane la sua conseguenza cambia natura, perché con 5xx e 429 la scansione rallenta e gli URL indicizzati vengono mantenuti per un periodo e poi lasciati cadere. Un 503 che nessuno toglie finisce dove finisce un 404, solo più lentamente e senza che l’abbia deciso qualcuno.

La scorciatoia che si prende al suo posto è peggiore: una pagina di cortesia servita con 200, quella che dice «torniamo presto». Quella risposta dichiara che il contenuto definitivo di quell’indirizzo è il messaggio di scuse, quindi può essere indicizzato al posto della pagina vera, e quando il sito torna ti ritrovi in indice la versione sbagliata da correggere.

Canonical e noindex servono quando togliere non è quello che vuoi. Se le pagine devono restare entrambe raggiungibili — varianti, filtri, versioni per la stampa — un redirect ne toglierebbe una dalla circolazione anche per chi la usa: il rel="canonical" indica quale versione consolidare lasciando l’altra accessibile, ed è una preferenza che il motore può non seguire. Il noindex fa un’altra cosa ancora, perché la pagina resta raggiungibile per le persone ed esce dai risultati. Metterli insieme sulla stessa pagina significa dichiarare che quella pagina è la copia secondaria di un’altra e insieme che non deve comparire: istruzioni diverse, e quale prevalga non lo decidi tu.

C’è infine una condizione che vale per qualunque destinazione tu scelga: deve essere una pagina che finisce in indice. AI Overview e AI Mode attingono all’indice della Ricerca, e per comparire lì una pagina deve essere indicizzata e idonea a essere mostrata con uno snippet: se mandi i vecchi URL su una destinazione che in indice non arriva, li togli da entrambe le superfici in una volta sola.

Il rischio di mandare tutto in home page

Da qualunque mappa, per quanto curata, avanza un residuo: gli indirizzi che nessuno ha saputo abbinare a niente. Per quel residuo esiste una riga che li prende tutti e li manda in home, e a prima vista è la scelta ragionevole — una regola sola al posto di centinaia di decisioni, e nessun 404 da spiegare a nessuno.

La guida di Google alle migrazioni dice che reindirizzare molti vecchi URL verso una singola destinazione non pertinente può essere trattato come un soft 404. Quelle pagine, quindi, escono dall’indice come sarebbero uscite comunque: la riga in home non ha evitato niente, ha solo tolto a te il modo di accorgertene, perché nei rapporti non compaiono più come indirizzi che rispondono con un errore.

Poi c’è il costo che nessun rapporto misura. Chi arriva da un link di tre anni fa si ritrova in home page senza una spiegazione, in un punto del sito che non c’entra con quello che stava cercando, e quel visitatore lo perdi lì. Un 404 curato, con la ricerca interna e i percorsi principali, gli dice almeno che cosa è successo e gli lascia un modo per proseguire.

La regola di raccolta serve — è la rete sotto la mappa, e senza rete resta scoperto quello che non avevi previsto — ma la sua destinazione è il 404, non la home. E quando l’erede esatto non c’è ma la categoria sì, la categoria è una destinazione legittima e non un ripiego, perché contiene lo stesso tipo di contenuto e permette di ripartire da lì. È l’ordine con cui si costruisce la mappa in qualunque migrazione: prima l’erede esatto, poi il livello superiore, e solo alla fine la risposta di rimozione.

Dove si imposta un redirect

Come ogni intervento di SEO tecnica, lo stesso redirect lo puoi dichiarare in più punti, e a rispondere è sempre il primo livello che intercetta la chiamata: se davanti c’è un CDN si ferma lì, e all’origine non arriva niente; se invece arriva e viene passata all’applicazione, può rispondere WordPress prima che il tuo .htaccess venga preso in considerazione. Quando un redirect non fa quello che credi, la prima cosa da stabilire è chi ha risposto, perché la correzione ha effetto solo nel livello che sta rispondendo. Il confronto fra la risposta che ricevi e i log dell’origine lo dice subito: se la chiamata nei log non compare, sta rispondendo qualcosa davanti.

  • Apache. Per i casi semplici bastano le direttive di mod_alias, che non richiedono espressioni regolari.
    Redirect 301 /vecchia-pagina/ https://www.esempio.it/nuova-pagina/
    RedirectMatch 301 ^/blog/(.*)$ https://www.esempio.it/articoli/$1

    Quando servono condizioni si passa a mod_rewrite, e il flag [R] è quello che trasforma una riscrittura interna in uno spostamento vero: senza, il server consegna un altro file lasciando l’indirizzo dov’era.

    RewriteEngine On
    RewriteRule ^prodotti/([0-9]+)/?$ /catalogo/$1/ [R=301,L]

    Sulla query string il comportamento predefinito è asimmetrico: se la sostituzione non ne contiene una, quella originale viene conservata; se ne introduce una, l’originale viene scartata. È così che i parametri di tracciamento di una campagna spariscono lungo il passaggio, e le visite che ne derivano vengono attribuite altrove. [QSA] accoda l’originale a quella nuova, [QSD] la elimina.

  • nginx. Le direttive stanno nella configurazione e richiedono un reload, quindi per toccarle serve accesso al server e nessuno le modifica per sbaglio.
    server {
        listen 443 ssl;
        server_name www.esempio.it;
    
        location = /vecchia-pagina/ {
            return 301 https://www.esempio.it/nuova-pagina/;
        }
    
        rewrite ^/blog/(.*)$ /articoli/$1 permanent;
    }

    return è più efficiente di rewrite e va preferito quando la corrispondenza è esatta. L’ordine dei blocchi location non segue quello del file ma le precedenze di nginx, e una corrispondenza esatta con = vince sulle altre: se la tua regola sembra ignorata, quasi sempre ne sta vincendo un’altra più specifica.

  • PHP. La funzione che imposta l’intestazione restituisce un 302 se non dichiari altro, ed è così che si pubblica uno spostamento permanente dichiarandolo temporaneo.
    header('Location: https://www.esempio.it/nuova-pagina/', true, 301);
    exit;

    Va chiamata prima che il server abbia inviato qualunque output — anche uno spazio fuori dai tag PHP conta — altrimenti ricevi un avviso e la pagina viene servita normalmente; se l’output parte comunque, ob_start() in cima allo script lo trattiene. E va seguita da exit, perché altrimenti lo script prosegue e il codice sotto viene eseguito lo stesso, con tutto quello che comporta se lì dentro ci sono scritture sul database.

  • WordPress. Le funzioni disponibili partono entrambe da 302 e nessuna interrompe l’esecuzione, quindi exit serve anche qui.
    add_action('template_redirect', function () {
        if (is_page('vecchia-pagina')) {
            wp_safe_redirect(home_url('/nuova-pagina/'), 301);
            exit;
        }
    });

    La differenza riguarda la destinazione. wp_safe_redirect() la valida e, se punta a un host non consentito, manda l’utente in wp-admin invece che fuori; l’elenco degli host si estende con il filtro allowed_redirect_hosts. wp_redirect() non valida niente, ed è quella da evitare ovunque la destinazione arrivi da un parametro: un endpoint che manda dove gli dice l’URL è un open redirect, e serve a far partire i visitatori verso un sito che non è il tuo tenendo il tuo dominio nel link. Se gestisci gli spostamenti con un plugin, tieni presente che diventa uno dei livelli che rispondono, e il primo posto in cui guardare quando una regola scritta nel server sembra non avere effetto.

  • CDN e reverse proxy. Il livello davanti risponde prima dell’origine, e produce effetti che si vedono soltanto se li cerchi. Le chiamate reindirizzate lì non compaiono nei log del tuo server, quindi cercarle lì ti fa concludere che quell’URL non lo chiede più nessuno. E Location, che secondo la RFC 9110 può contenere sia un indirizzo assoluto sia un riferimento relativo risolto rispetto all’URL chiesto, con un riferimento relativo dietro un proxy che cambia host si finisce sull’host sbagliato.Se il tuo passaggio a HTTPS è impostato sull’origine mentre la terminazione TLS avviene sull’edge, l’origine vede sempre una richiesta HTTP e rimanda a HTTPS all’infinito: è l’uso di X-Forwarded-Proto, ed è il motivo per cui quel loop compare solo in produzione. C’è infine uno spostamento che vedrai nel browser senza averlo scritto: con HSTS attivo il browser converte da solo le chiamate a HTTP prima di uscire e lo registra come 307 Internal Redirect, che non arriva dal tuo server e nella configurazione non lo troverai mai.

    Il livello davanti, poi, può generare spostamenti per conto suo e per una sola categoria di chiamanti. Redirects for AI Training di Cloudflare applica i tuoi rel="canonical" come 301 verso i crawler di addestramento verificati, quando il canonical punta a un altro URL dello stesso host, e lascia la pagina invariata per browser, motori di ricerca e assistenti. È un redirect che esiste per qualcuno e non per altri, e nella configurazione del tuo server non compare.

Quando .htaccess non viene letto

Una regola corretta può non produrre nessun effetto, e la causa più frequente sta altrove. Il valore predefinito di AllowOverride è None, e con quel valore i file .htaccess vengono ignorati del tutto: quello che hai scritto non è sbagliato, semplicemente non lo legge nessuno. AllowOverrideList permette di abilitare singole direttive senza aprire tutto.

L’ereditarietà fa sparire una regola corretta in un altro modo. Quando unisce sezioni dello stesso contesto, mod_rewrite di default sostituisce le regole invece di aggiungerle, quindi un .htaccess in una sottodirectory può azzerare quello superiore; RewriteOptions Inherit, InheritBefore e InheritDown cambiano questo comportamento.

Se invece hai usato una direttiva non ammessa in quel contesto, il server risponde 500 su tutta la directory e nel log compare una riga che nomina la direttiva rifiutata. Dalla pagina di errore quel nome non si ricava: sta solo lì.

Da HTTP a HTTPS e da www a non-www

Il protocollo e il prefisso dell’host non riguardano una pagina ma tutte quante, e proprio per questo vengono quasi sempre decisi in momenti diversi, da persone diverse. Il risultato tipico è una catena: http://www che manda a https://www, che manda a https://, con due passaggi dove ne basta uno. A pagarli è ogni chiamata che entra dalla forma vecchia, cioè quella scritta dentro i link pubblicati anni fa e dentro i preferiti di chi il sito lo conosce da prima.

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

Una regola sola che porta alla forma finale in un passaggio vale più di due regole corrette scritte separatamente, e quando le trovi già stratificate conviene riscriverle insieme invece di aggiungerne una terza. La verifica è immediata: chiedi la forma più lontana, http://www, e conta i blocchi che tornano indietro.

Destinazioni diverse per lingua e per paese

Uno spostamento che cambia destinazione secondo l’IP o l’Accept-Language sembra funzionare perché lo provi da dove sei. Googlebot scansiona prevalentemente da indirizzi statunitensi, quindi di tutto il tuo sito multilingua vede una versione sola, e quella è l’unica che può finire in indice.

Google indica come alternativa le pagine adattive, che servono contenuti diversi sullo stesso URL, oppure indirizzi separati per lingua collegati con hreflang. In entrambi i casi ogni versione resta raggiungibile da chiunque, che è la condizione perché venga scansionata.

Redirect in una migrazione

A rendere difficile una migrazione non è il numero degli indirizzi ma la loro eterogeneità: mille URL con lo stesso schema si coprono con una regola sola, cinquanta senza schema sono cinquanta decisioni da prendere a mano.

Il lavoro, quindi, non comincia dalle regole ma dalla mappa: l’elenco dei vecchi indirizzi con accanto la destinazione scelta per ciascuno. È la parte che non si delega, ed è anche quella che rende meccanico tutto il resto, perché una volta che la mappa esiste scrivere le regole diventa un problema di sintassi. Quello che nella mappa non entra non riceve nessuna risposta, e non te ne accorgi, perché a chiedere quell’indirizzo non sei tu.

Dove si trovano i vecchi URL

Nessuna fonte da sola contiene l’elenco completo, e ciascuna ha un punto cieco che dipende da come è fatta.

La sitemap è la più comoda e la più parziale: raccoglie quello che il sito dichiara oggi, cioè quello che il CMS considera pubblicato, e non sa niente degli indirizzi che hai dismesso negli anni né di quelli che il CMS non genera — i PDF, le landing costruite a mano, i percorsi di una vecchia piattaforma. I log del server contengono l’opposto: non quello che dichiari, ma quello che è stato effettivamente chiesto, compresi gli indirizzi che non ricordavi di avere. Ci trovi anche le chiamate dei crawler generativi, che lavorano su inventari non aggiornati: gli URL che continuano a chiedere sono vecchi per definizione, ed è una lista che nessun’altra fonte ti mette insieme. Il loro limite è la finestra temporale, perché di solito vengono ruotati dopo qualche settimana, e un URL chiamato due volte l’anno non compare.

Search Console mostra quello che Google ha visto, ed è la fonte che ti dà anche l’informazione su chi linka che cosa, ma i suoi rapporti sono campionati e gli elenchi di esempio hanno un tetto. I backlink danno gli indirizzi che altri hanno pubblicato, che sono i più importanti perché sono quelli che continueranno a essere chiamati per anni, e sono anche quelli che nel tuo CMS potrebbero non esistere più da tempo. Una scansione del sito, infine, trova quello che è raggiungibile navigando: lascia fuori le pagine orfane, cioè proprio quelle che nessun link interno raggiunge e che quindi non ti verranno in mente.

Le fonti si incrociano perché i punti ciechi non coincidono, e l’ordine in cui le usi cambia il risultato. Si parte dai backlink e dai log, che danno gli indirizzi vivi anche se dimenticati; si aggiunge la scansione, che dà la struttura attuale; si chiude con sitemap e Search Console per il controllo incrociato. Quello che ne esce resta un’approssimazione: per questo una regola di fallback che raccoglie i casi non previsti serve sempre, anche quando pensi di aver mappato tutto.

Quali indirizzi hanno la precedenza

Una mappa di qualche migliaio di righe non si pubblica e non si verifica in un pomeriggio, e quasi nessun rilascio è istantaneo: si procede per blocchi, o per rami del sito. Questo vuol dire che qualche indirizzo la sua regola ce l’ha dal primo giorno e qualche altro la riceve settimane dopo, e nel frattempo chi chiama i secondi trova un 404. L’ordine, quindi, non è una questione di comodità: decide quali indirizzi passano scoperti il periodo più lungo.

A stabilirlo non è il volume di ricerca delle keyword associate, che dice quanto si cerca un tema e non quanto vale per te quella pagina. Lo stabiliscono i link ricevuti da altri siti, che sono la cosa che non puoi ricostruire e che continuerà ad arrivare per anni; la presenza nei risultati, perché quegli indirizzi sono già in circolazione e vengono ripresi dai motori; e le chiamate nei log, che dicono chi sta usando quell’URL adesso, comprese le integrazioni e i feed che nessun altro strumento vede.

La visibilità, qui, va presa per quello che è: una stima della presenza nei risultati, non una misura di traffico, perché nessuna posizione garantisce un numero di clic. Serve a mettere in fila i tuoi URL fra loro, non a dire quanto ne arriverà su ciascuno.

Le tre letture stanno in posti diversi e nessuna si fa per keyword, perché la domanda non è quali temi portano ricerche ma quali indirizzi stanno lavorando. Per la parte Search Console significa guardare i dati aggregati per URL invece che per query: è la vista di Performance Pagine, che per ogni indirizzo tiene insieme clic, impressioni, posizione media e numero di keyword, e ti consente di ordinare la lista prima di cominciare. I link in ingresso li leggi con l’analisi dei backlink, le chiamate nei log dal server: si incrociano, e dove le tre cose coincidono hai il primo blocco da rilasciare.

Gli indirizzi che restano fuori da quel blocco non vanno lasciati a sé stessi fino al loro turno: è esattamente il lavoro della regola di raccolta, che li porta alla categoria o a un 404 curato invece che a una risposta muta.

Che cosa dichiarare a Search Console

Durante lo spostamento Google indica di tenere in Search Console due sitemap, quella dei vecchi indirizzi e quella dei nuovi. All’inizio la nuova ha zero pagine indicizzate e la vecchia molte, e vedere come le cifre si invertono ti dice a che punto è la migrazione meglio di qualunque altra cosa tu possa guardare: quando l’inversione è completa il passaggio è finito, e la sitemap vecchia si rimuove.

Il cambio di indirizzo è un’altra cosa e serve in un caso solo, cioè quando il sito si sposta su un dominio diverso: lì lo dichiari esplicitamente e Google lo tratta come tale. Se cambia soltanto la struttura degli URL e il dominio resta quello, non c’è niente da comunicare e contano le regole che hai scritto.

I limiti di una regex scritta in fretta

Un’espressione regolare che riscrive un intero ramo del sito funziona finché il rapporto fra vecchio e nuovo è davvero regolare, e cede sui casi limite che non avevi in mente quando l’hai scritta. Una regola come ^/blog/(.*)$ verso /articoli/$1 sembra coprire tutto, e intanto prende anche /blog/ senza slug, che finisce su /articoli/ anche quando quella pagina non esiste; e basta scriverla senza lo slash finale, ^/blog(.*)$, perché si porti dietro anche /blogger/; e passa oltre i percorsi con caratteri accentati o codificati, dove %C3%A8 e è non sono la stessa stringa.

Poi ci sono i parametri, che una regex costruita sul percorso non vede, e le maiuscole, che su un filesystem case sensitive fanno due indirizzi diversi dello stesso contenuto. Prima del rilascio la regola va provata su una lista di casi limite scelti a mano — uno per ciascuna di queste forme — e non sui tre URL che hai usato per scriverla, che sono quelli su cui funziona per costruzione.

Resta poi la parte che una regola non può fare. Una regex sa trasformare un percorso in un altro percorso: non sa se la pagina di arrivo parla della stessa cosa. Su un ramo omogeneo la trasformazione basta; dove i contenuti sono stati riorganizzati, ogni corrispondenza va decisa e la regola serve solo a coprire quello che avanza.

Verificare i redirect, da un URL a tutto il sito

Il browser ti conferma la destinazione e nasconde tutto il resto: con quale codice il server ha risposto, quanti passaggi ha fatto la chiamata, che cosa riceve chi non sta usando un browser.

Recuperare quelle informazioni è un lavoro che cambia con la scala. Su un indirizzo singolo la risposta si legge per intero, riga per riga, e non c’è niente da interpretare. Sull’intero sito non puoi leggere niente per intero: costruisci un elenco e ci cerchi dentro le anomalie, e a quel punto la qualità del controllo dipende da quale strumento ha costruito l’elenco. Resta fuori da entrambe le letture la parte più insidiosa, cioè che cosa risponde quell’indirizzo quando a chiedere è qualcun altro.

Leggere gli header con curl e DevTools

Da riga di comando, l’opzione che segue i rimandi mostra la sequenza completa delle risposte.

curl -sIL https://www.esempio.it/vecchia-pagina/

Ogni blocco è una risposta: il codice sta sulla prima riga e l’intestazione Location poco sotto, e il numero di blocchi ti dice quanti passaggi ci sono stati. Senza -L vedresti solo il primo, ed è già un’informazione: è il comportamento di un client che i redirect non li segue.

Quel comportamento, del resto, cambia da programma a programma, ed è la ragione per cui un controllo solo non basta. Il browser segue in automatico fino a un numero massimo di passaggi, oltre il quale si ferma e dichiara l’errore. curl, appunto, non segue se non glielo chiedi. L’integrazione scritta da un partner può fermarsi al primo 3xx e restituire quella risposta così com’è, perché a chi l’ha scritta interessava il contenuto e non la deviazione: per quel programma il tuo indirizzo, da quando l’hai spostato, non restituisce più dati utili. L’opzione -I aggiunge un’altra variabile, perché invia una richiesta HEAD che alcuni server trattano diversamente da GET: se il risultato ti sembra strano, conviene ripetere con -sL -o /dev/null -w "%{http_code}\n" e confrontare.

Nel browser lo stesso lavoro si fa nel pannello Network degli strumenti per sviluppatori, a una condizione che conviene sistemare prima di guardare: senza Preserve log attivo la navigazione ripulisce la lista, e il passaggio intermedio sparisce prima che tu riesca a vederlo.

Le catene di redirect e i loop

Le catene non le scrive nessuno: si formano una regola alla volta, e ogni regola era corretta quando è stata aggiunta. Si sommano proprio perché ciascuna, presa da sola, non dà fastidio a nessuno — il passaggio in più costa pochi millisecondi, non compare in nessun rapporto, non rompe niente. Il dominio cambia, poi cambia la struttura, poi due pagine vengono unite, e l’indirizzo di tre anni fa arriva a destinazione attraversando tre risposte scritte da persone diverse in momenti diversi.

I crawler di Google seguono fino a dieci salti in una singola sessione di scansione, quindi una catena breve non ti fa perdere l’indicizzazione. La guida alle migrazioni consiglia comunque di restare idealmente sotto i tre passaggi e in ogni caso sotto i cinque, e la ragione riguarda te più di Google: ogni salto è un punto in cui qualcosa può rompersi in futuro, e più la catena è lunga meno è probabile che chi la tocca sappia perché ogni passaggio si trova lì.

Lo strumento di controllo URL di Search Console, va tenuto presente, non segue i redirect: ti dice che l’indirizzo reindirizza, non dove finisce.

Il loop è il caso in cui la catena si chiude su sé stessa. Il browser si ferma da solo dopo un certo numero di tentativi e mostra un errore di troppi reindirizzamenti; il caso tipico sono due regole scritte in livelli diversi, una sul server e una nell’applicazione, che si rimandano la richiesta a vicenda.

La scansione dell’intero sito

Su un sito intero i comandi non bastano, e lo strumento cambia secondo quello che stai cercando: i redirect che hai già sul sito, quelli che stai per pubblicare, quelli che Google ha effettivamente incontrato.

I redirect che hai già li trova una scansione che parte dai link. Il SEO Spider di SEOZoom naviga il sito e distribuisce gli URL trovati nel gruppo Response Codes, dove la vista dei 3xx dà per ogni indirizzo il codice e la destinazione. Quei 3xx compaiono perché lo spider segue i link interni, quindi ognuno è un collegamento che dentro il tuo sito punta ancora al vecchio indirizzo: sono i link che Google chiede di aggiornare, l’unica parte del circuito su cui hai controllo diretto, e correggerli toglie un passaggio a ogni visita. Quello che questa vista non fa è ricostruire le catene: dice dove porta l’indirizzo di partenza, non dove porta quello di arrivo, e per saperlo devi interrogare a tua volta la destinazione.

L’elenco preparato prima di un rilascio chiede invece uno strumento che accetti la lista senza navigare il sito. Screaming Frog lavora in list mode, e la configurazione che rende utile il controllo è Always follow redirects, nella scheda advanced: in list mode la profondità di scansione è zero, cioè vengono chiamati soltanto gli URL caricati, mentre con quell’opzione attiva lo strumento segue ogni catena fino alla risposta finale, che sia un 2xx, un 4xx o un 5xx. Il report All Redirects restituisce poi ogni indirizzo dell’elenco con quello di arrivo, il codice emesso da ciascuno, il numero di salti, il tipo di catena — redirect HTTP, JavaScript o meta refresh — e una colonna che dichiara se si chiude in loop. È il controllo che prima del rilascio vale più di ogni altro, perché confronta quello che hai scritto con quello che succede a ciascuno degli indirizzi che ti interessano. Per una manciata di URL bastano i verificatori via web, e le estensioni che mostrano la catena mentre navighi restano comode per i controlli al volo.

Quello che Google ha incontrato, infine, non lo trova nessuna scansione: lo dice solo Google. Nel rapporto Pagine di Search Console i vecchi indirizzi finiscono sotto «Page with redirect», e quella lista non descrive il tuo sito ma quello che il motore ne ha visto, con un campione di mille URL di esempio che serve a controllare, non a contare. Un indirizzo che lì non compare non è per forza un indirizzo a posto: può essere uno che Google non ha ancora ripreso in mano, o uno che non ha mai visto.

Qualunque scansione, infine, la esegue un chiamante solo: gli spostamenti condizionali le sfuggono, e si riproducono con l’opzione -A di curl per cambiare user agent, o dal pannello degli strumenti per sviluppatori.

Gli errori più comuni

Quasi tutti i problemi hanno una causa fra poche, e si isolano per esclusione, in un ordine che conviene rispettare. Si parte da chi ha emesso la risposta, perché finché non lo sai stai correggendo a caso: il codice te lo dà curl, il livello te lo dicono i log dell’origine, e se la chiamata lì non compare ha risposto qualcosa davanti.

Si guarda poi se la regola non è stata raggiunta o se è stata raggiunta e ha fatto un’altra cosa, perché sono guasti con cause diverse. Nel primo caso il vecchio indirizzo risponde 200 come se niente fosse, e il problema è a monte — l’ordine nel file, un .htaccess che non viene letto, un livello che risponde prima. Nel secondo parte un 3xx, ma il codice, la destinazione o il numero di passaggi non sono quelli che hai scritto, e lì la causa sta nella regola o in una seconda regola a valle.

Dal sintomo alla causa, e come si conferma
Che cosa vedi Prima ipotesi Come la confermi
Non succede niente, la vecchia pagina risponde normalmente la regola non viene mai raggiunta: ordine nel file, .htaccess ignorato, un livello che risponde prima controlla AllowOverride, l’ordine nel file e i log dell’origine
Il redirect parte ma il codice è diverso da quello che hai scritto un default non dichiarato in PHP o WordPress, oppure un secondo redirect a valle curl -sIL e leggi tutti i passaggi, non solo il primo
Vai ancora al vecchio indirizzo anche dopo la correzione cache del client su un permanente precedente prova in finestra anonima o con curl, che quella cache non ce l’ha
La destinazione è giusta ma i passaggi sono tre regole stratificate in momenti diversi conta i blocchi nella risposta di curl -sIL
Il redirect porta a una pagina che risponde 404 la destinazione è cambiata dopo che la regola era stata scritta scansione del sito filtrata sui 3xx, e verifica delle destinazioni
Funziona per te e non per Google condizione su IP, lingua o user agent riproduci la condizione con curl -A

I reindirizzamenti malevoli sui siti compromessi

Esiste una categoria di reindirizzamenti che non hai scritto tu. Le norme antispam di Google li classificano come ingannevoli e li trattano come violazione, e sui siti compromessi sono uno degli effetti più comuni: il sito funziona normalmente per chi lo amministra e manda altrove i visitatori che arrivano dai risultati di ricerca.

Il caso tipico si attiva in modo condizionale, per un certo user agent o per chi proviene da un referrer specifico, proprio per restare invisibile a chi controlla. Il rapporto sui problemi di sicurezza di Search Console è il primo posto in cui la segnalazione compare; poi si cerca nei file del tema, nel .htaccess, nel database e negli script caricati dall’esterno, e la verifica si fa riproducendo la condizione: se un indirizzo si comporta diversamente a seconda di come lo chiami, e quella differenza non l’hai scritta tu, l’hai trovata.

Dopo la pubblicazione

Con tutto in produzione il lavoro cambia oggetto: non controlli più le tue regole, controlli se il nuovo indirizzo ha preso il posto del vecchio per chi non hai avvisato. Il passaggio però non avviene nel tuo tempo, avviene in quello di chi ripassa: Google indica che per un sito di dimensioni medie servono alcune settimane perché la maggior parte delle pagine si sposti, e che nel frattempo le oscillazioni di posizionamento sono normali mentre il sito viene riscansionato e reindicizzato. Chi legge i dati della prima settimana come un risultato finisce per correggere regole che non erano rotte, e ogni correzione aggiunge un passaggio a quelli che ci sono già.

Lo stato di avanzamento, in Search Console, si legge in negativo. I vecchi indirizzi compaiono sotto «Page with redirect», che nel rapporto Indicizzazione delle pagine sta fra le pagine non indicizzate e non è un errore ma la conferma che il redirect è stato visto; l’elenco di URL di esempio si ferma a mille elementi, quindi dice che cosa sta succedendo e non quanto ne resta. Per quello servono le due sitemap, nel rapporto fra le pagine indicizzate della vecchia e quelle della nuova.

Per quanto tempo tenere attivi i redirect

Un redirect non ha una scadenza tecnica: resta finché qualcuno non lo toglie, e toglierlo è l’unica operazione che nessuno mette in calendario. L’indicazione di Google è di tenerlo il più a lungo possibile, in genere almeno un anno, e dal punto di vista di chi naviga di considerarlo permanente.

Nella stessa guida, però, c’è l’avvertenza che cambia la lettura: i redirect sono lenti per chi naviga, quindi i propri link vanno aggiornati invece di lasciare che tutti passino da lì. Le indicazioni non si contraddicono, perché parlano di riferimenti diversi, ed è su quella distinzione che si decide: la regola resta accesa per i riferimenti che non puoi correggere — i link su siti altrui, i preferiti, le email partite — mentre tutto quello che controlli tu va riscritto alla destinazione finale.

Dopo un anno, quindi, la domanda non è se togliere i redirect ma quali, e si risponde indirizzo per indirizzo con verifiche che hai già fatto durante la migrazione. Nei log dell’origine quel vecchio URL riceve ancora chiamate, e da chi: se arrivano da persone o da crawler, la regola sta lavorando. Fuori dal sito riceve ancora link, e da pagine che contano: se sì, toglierla trasforma quei link in 404 con il tuo dominio davanti. Dentro il sito c’è ancora un collegamento che ci passa: in quel caso non è la regola da togliere, è il link da riscrivere.

A questo si aggiunge una ragione che qualche anno fa non c’era, e che si misura. Nella rilevazione di Vercel e MERJ il 34,82% delle chiamate di ChatGPT e il 34,16% di quelle di Claude finiscono su pagine che non esistono, e un altro 14,36% delle chiamate di ChatGPT viene speso seguendo redirect. Sono crawler che lavorano su inventari di indirizzi vecchi: la parte delle loro chiamate che non muore in un 404 arriva a destinazione soltanto perché una tua regola è ancora accesa, e il giorno in cui la togli quelle chiamate passano nel primo gruppo. Lo stesso vale per le risposte generate che ti citano: l’indirizzo che compare nella citazione può essere quello raccolto prima del cambio.

Tenerle accese, però, non è gratis nemmeno per te. Ogni regola è un caso in più da considerare quando ne scrivi una nuova, e una configurazione lunga è una configurazione che nessuno rilegge: è così che nascono le catene. La differenza fra un impianto e una stratificazione sta qui — restano le regole che qualcuno chiama ancora, non quelle che nessuno ha voglia di verificare.

Misurare l’effetto sul rendimento

Il confronto fra prima e dopo ha un problema che nasce dallo spostamento stesso: gli indirizzi non sono più gli stessi, quindi una lettura URL per URL mette a paragone due liste che non combaciano. Quello che resta confrontabile sono gli insiemi — le keyword su cui il sito è visibile e le pagine che le tengono, prima e dopo. È il taglio di Confronto Periodi, che affianca due intervalli e separa quello che è stato guadagnato da quello che è stato perso, con un limite da tenere presente: cinquemila keyword per periodo, che su un sito grande vuol dire leggere la parte alta e non l’intero insieme. Sugli indirizzi rimasti uguali il dettaglio da Search Console lo dà Performance Pagine. Anche qui la lettura va tarata su quello che i numeri sono: una stima della presenza nei risultati, che serve a confrontare due momenti dello stesso sito e non a prevedere quanti clic arriveranno.

Se la visibilità cala, la causa non è il passaggio in sé, perché i permanenti non fanno perdere PageRank, e cercarla lì fa perdere tempo. Restano gli indirizzi rimasti scoperti e le destinazioni scelte male, che sono anche le sole su cui puoi ancora intervenire.

Il redirect che resta

Un reindirizzamento ha finito il suo lavoro quando i riferimenti che lo attraversano sono solo quelli che non puoi correggere. Da quel momento non lo togli perché non serve più: lo tieni perché serve a qualcuno che non conosci, e perché toglierlo costa a lui e non a te.

È la parte del sito che continua a rispondere quando tutto il resto è cambiato. Vale la pena sapere che cosa dice.

Prova SEOZoom

7 giorni di Prova Gratuita

Aumenta la tua visibilità online con SEOZoom!
TOP