WPML e Permalink Manager: doppio URL con slug di un’altra lingua e risposta 200, come risolvere

Wpml E Permalink Manager: Doppio Url Con Slug Di Un’altra Lingua E Risposta 200, Come Risolvere

Il problema: due URL diversi mostravano la stessa pagina WordPress

Mi sono trovata davanti a un comportamento piuttosto particolare su un sito WordPress multilingua che utilizza WPML insieme a Permalink Manager Lite.

Una pagina in lingua inglese aveva correttamente questo permalink:

/en/how-to-start-an-online-discount-store/

Il problema era che risultava perfettamente raggiungibile anche utilizzando lo slug della corrispondente pagina francese:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

Entrambi gli URL restituivano:

HTTP 200 OK

e mostravano esattamente la stessa pagina in inglese.

Dal punto di vista SEO non è una situazione ideale: due URL diversi in grado di restituire lo stesso contenuto possono creare duplicazioni, sprecare crawl budget e rendere più difficile comprendere quale URL debba essere considerato quello principale.

La cosa ancora più curiosa era che il canonical risultava corretto.

Aprendo:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

nel codice HTML era presente:

<link rel="canonical" href="https://www.example.com/en/how-to-start-an-online-discount-store/">

Quindi WordPress e il sistema SEO sapevano perfettamente quale fosse l’URL corretto.

Il problema era un altro: perché l’URL con lo slug francese continuava a essere considerato valido e restituiva HTTP 200 anziché un redirect o un 404?

La configurazione iniziale

Il sito utilizzava:

  • WordPress;
  • WPML per la gestione delle lingue;
  • Permalink Manager Lite per la gestione personalizzata dei permalink;
  • URL delle lingue organizzati tramite directory, ad esempio /fr/ e /en/.

La pagina francese aveva uno slug simile a:

comment-lancer-une-boutique-de-reductions-en-ligne

mentre la sua traduzione inglese utilizzava correttamente:

comment-lancer-une-boutique-de-reductions-en-ligne

La situazione che si presentava era quindi questa:

/fr/comment-lancer-une-boutique-de-reductions-en-ligne/   → pagina francese

/en/how-to-start-an-online-discount-store/       → pagina inglese

/en/comment-lancer-une-boutique-de-reductions-en-ligne/   → pagina inglese(!)

L’ultimo URL, teoricamente, non sarebbe dovuto esistere.

Primo tentativo: controllare lo slug WordPress e Permalink Manager

La prima ipotesi era piuttosto logica: da qualche parte doveva essere stato memorizzato il vecchio permalink.

Ho quindi controllato sia lo slug nativo di WordPress sia quello gestito da Permalink Manager.

Nella pagina inglese lo slug risultava correttamente:

how-to-start-an-online-discount-store

Anche il permalink mostrato da Permalink Manager era corretto.

Non c’era quindi nessuna traccia evidente dello slug:

comment-lancer-une-boutique-de-reductions-en-ligne

associato alla pagina inglese.

Questo escludeva il caso più semplice: un permalink personalizzato errato salvato direttamente sulla pagina.

Secondo tentativo: controllare _wp_old_slug

WordPress conserva alcuni vecchi slug nel database utilizzando il meta field:

_wp_old_slug

Questo permette, ad esempio, di redirigere automaticamente un vecchio indirizzo quando viene modificato lo slug di un articolo.

Ho quindi verificato se lo slug francese fosse stato memorizzato come vecchio slug della pagina inglese.

Una possibile query è:

SELECT post_id, meta_key, meta_value
FROM wp_postmeta
WHERE meta_key = '_wp_old_slug'
AND meta_value IN (
    'comment-lancer-une-boutique-de-reductions-en-ligne',
    'how-to-start-an-online-discount-store'
);

Il risultato, però, non spiegava il problema.

Lo slug francese non risultava registrato come _wp_old_slug della pagina inglese.

Inoltre, un vecchio slug WordPress avrebbe normalmente dovuto portare a un redirect verso il nuovo permalink, non necessariamente al caricamento diretto della pagina con status HTTP 200.

Era quindi necessario continuare a cercare.

Terzo tentativo: verificare eventuali contenuti duplicati nel database

Un’altra possibilità era l’esistenza di due pagine distinte che apparentemente visualizzavano lo stesso contenuto.

Per verificarlo è possibile interrogare wp_posts:

SELECT
    ID,
    post_title,
    post_name,
    post_status,
    post_type
FROM wp_posts
WHERE post_name IN (
    'comment-lancer-une-boutique-de-reductions-en-ligne',
    'how-to-start-an-online-discount-store'
);

In un sito WPML è utile controllare anche la relazione tra le traduzioni.

Ad esempio:

SELECT
    p.ID,
    p.post_title,
    p.post_name,
    t.language_code,
    t.source_language_code,
    t.trid
FROM wp_posts p
INNER JOIN wp_icl_translations t
    ON t.element_id = p.ID
    AND t.element_type = CONCAT('post_', p.post_type)
WHERE p.post_name IN (
    'comment-lancer-une-boutique-de-reductions-en-ligne',
    'how-to-start-an-online-discount-store'
)
ORDER BY t.trid, t.language_code;

Il risultato mostrava correttamente due pagine appartenenti allo stesso gruppo di traduzione WPML:

FR   comment-lancer-une-boutique-de-reductions-en-ligne
EN   how-to-start-an-online-discount-store

Nessuna pagina inglese utilizzava lo slug francese.

Anche questa ipotesi poteva quindi essere esclusa.

Ho sospettato che WPML conservasse lo slug da qualche altra parte

A questo punto il sospetto si è spostato su WPML.

La domanda era:

WPML potrebbe conservare da qualche parte lo slug originale della traduzione e continuare a utilizzarlo per risolvere gli URL?

Ho controllato le relazioni WPML e le principali informazioni memorizzate nelle tabelle icl_*, senza però trovare un secondo permalink associato alla pagina inglese.

Ed è qui che il problema iniziava a diventare interessante.

Lo slug apparentemente “fantasma” non era memorizzato sulla pagina inglese.

Il canonical era corretto, ma l’URL sbagliato continuava a rispondere 200

Il canonical forniva però un indizio importante.

L’URL:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

restituiva la pagina inglese ma dichiarava come canonical:

/en/how-to-start-an-online-discount-store/

Questo significava che il sistema conosceva il permalink corretto.

Il problema era quindi probabilmente nella fase precedente: la risoluzione della richiesta HTTP.

Qualcosa stava dicendo a WordPress:

Anche se l’utente ha richiesto /pl/comment-lancer-une-boutique-de-reductions-en-ligne/, so quale contenuto vuole vedere.

Il sospetto principale è quindi diventato Permalink Manager.

Il test decisivo: disattivare Permalink Manager

Ho effettuato il test più semplice ma anche quello che ha permesso di circoscrivere definitivamente il problema.

Ho disattivato temporaneamente Permalink Manager e richiesto nuovamente:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

Questa volta il risultato era:

404 Not Found

Perfetto.

WPML e WordPress, da soli, non consideravano valido quell’URL.

Riattivando Permalink Manager:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

tornava invece a rispondere:

200 OK

A questo punto il responsabile era praticamente individuato.

Ma Permalink Manager non conteneva quello slug

Qui arrivava il secondo aspetto particolare del problema.

Permalink Manager salva diverse informazioni all’interno di wp_options, tra cui URI e redirect.

Ho quindi cercato la stringa:

comment-lancer-une-boutique-de-reductions-en-ligne

nelle opzioni del plugin e, più in generale, in wp_options.

Ad esempio:

SELECT option_name, option_value
FROM wp_options
WHERE option_value LIKE '%comment-lancer-une-boutique-de-reductions-en-ligne%';

Ma non risultava nessuna associazione tra quello slug e la pagina inglese.

All’inizio sembrava un controsenso:

  • Permalink Manager era sicuramente responsabile;
  • disattivandolo l’URL diventava 404;
  • ma lo slug incriminato non risultava salvato da Permalink Manager.

La spiegazione era che Permalink Manager non stava leggendo un secondo URL dal database: lo stava ricostruendo dinamicamente sfruttando la relazione tra le lingue WPML.

La vera causa: “WPML/Polylang fix language mismatch”

Nelle impostazioni di Permalink Manager è presente una funzione dedicata alla compatibilità con i plugin multilingua:

WPML/Polylang fix language mismatch

A seconda della versione del plugin, questa impostazione può prevedere comportamenti equivalenti a:

Disable

Load the language variant of the requested page

oppure:

Redirect to the language variant of the requested page

Nel mio caso era attiva la modalità che caricava la variante linguistica corrispondente alla pagina richiesta.

Ed era esattamente questo a generare il comportamento anomalo.

Cosa accadeva realmente

Supponiamo di avere queste due traduzioni:

Francese
/fr/comment-lancer-une-boutique-de-reductions-en-ligne/

Inglese
/en/how-to-start-an-online-discount-store/

Quando veniva richiesto:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

Permalink Manager era in grado di riconoscere lo slug:

comment-lancer-une-boutique-de-reductions-en-ligne

come appartenente alla pagina francese.

Contemporaneamente rilevava che l’URL richiesto utilizzava la lingua inglese:

/en/

Grazie all’integrazione con WPML poteva quindi ragionare in questo modo:

comment-lancer-une-boutique-de-reductions-en-ligne
        ↓
pagina francese
        ↓
WPML
        ↓
trova la traduzione inglese
        ↓
carica la pagina inglese

Il risultato finale era:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/
        ↓
200 OK
        ↓
contenuto della pagina inglese

Ecco perché non esisteva nessuno “slug fantasma” nel database.

L’URL veniva interpretato dinamicamente.

Il comportamento è coerente con il funzionamento di Permalink Manager, che individua i contenuti utilizzando l’URI completo e non si affida esclusivamente alle normali rewrite rules di WordPress.

Perché il Canonical Redirect non risolveva il problema

Un’altra cosa che inizialmente poteva trarre in inganno era che nelle impostazioni di Permalink Manager risultava già attivo:

Canonical redirect

Mi sarei quindi aspettata:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/
        ↓
301
        ↓
/en/how-to-start-an-online-discount-store/

Invece ricevevo un 200.

La spiegazione è che “Canonical redirect” e “WPML/Polylang fix language mismatch” gestiscono due aspetti diversi della richiesta.

Il plugin può identificare la pagina appartenente a un’altra lingua e sostituirla con la relativa traduzione prima che il normale meccanismo di canonicalizzazione produca il risultato che ci aspetteremmo.

Il codice corrente di Permalink Manager mostra infatti sia l’opzione canonical_redirect sia l’opzione separata fix_language_mismatch, confermando che si tratta di due impostazioni indipendenti.

La soluzione

La soluzione è stata modificare:

Permalink Manager → Settings → WPML/Polylang fix language mismatch

passando dal caricamento diretto della variante linguistica alla modalità:

Redirect to the language variant of the requested page

In questo modo, richiedendo:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

il comportamento diventa:

HTTP 301
Location: /en/how-to-start-an-online-discount-store/

e infine:

/en/how-to-start-an-online-discount-store/
HTTP 200

Esattamente ciò che volevo ottenere.

In alternativa è possibile disattivare completamente il sistema di correzione del language mismatch, facendo sì che una combinazione non valida tra lingua e slug restituisca un errore.

Nel mio caso ho preferito il redirect perché l’URL errato poteva essere già stato scoperto o indicizzato dai motori di ricerca.

Come verificare che la correzione funzioni

Dopo aver modificato l’impostazione consiglio di:

  1. salvare nuovamente i permalink da Impostazioni → Permalink;
  2. svuotare eventuali cache WordPress;
  3. svuotare la cache del server o della CDN;
  4. verificare nuovamente gli URL.

Da terminale si può effettuare un controllo molto semplice:

curl -I https://www.example.com/en/comment-lancer-une-boutique-de-reductions-en-ligne/

Prima della modifica il risultato era simile a:

HTTP/2 200

Dopo la correzione dobbiamo invece trovare:

HTTP/2 301
location: https://www.example.com/en/how-to-start-an-online-discount-store/

Il secondo URL deve poi restituire normalmente:

HTTP/2 200

Canonical e redirect non sono la stessa cosa

Questa esperienza è anche un buon esempio di un concetto SEO che spesso genera confusione.

Avere:

<link rel="canonical" href="URL-CORRETTO">

su un URL duplicato non equivale a effettuare un redirect.

Il canonical è un’indicazione fornita ai motori di ricerca.

Il redirect HTTP, invece, impedisce effettivamente al browser e al crawler di considerare quella risorsa come una pagina autonoma.

Nel mio caso avevo:

URL errato
HTTP 200

Canonical:
URL corretto

La situazione era quindi migliore rispetto ad avere due canonical autoreferenziali, ma continuavo comunque ad avere due URL navigabili per lo stesso contenuto.

La soluzione più pulita era:

URL errato
301
↓
URL corretto
200

Una checklist per problemi simili con WPML e Permalink Manager

Se su un sito WordPress multilingua due URL diversi mostrano lo stesso contenuto, consiglio di controllare nell’ordine:

1. Lo slug nativo WordPress

Verificare post_name in wp_posts.

2. Il permalink personalizzato

Controllare l’URI visualizzato da Permalink Manager.

3. _wp_old_slug

Cercare eventuali vecchi slug memorizzati da WordPress.

4. Le traduzioni WPML

Verificare wp_icl_translations, soprattutto:

element_id
language_code
trid

per essere sicuri che non esistano traduzioni duplicate o relazioni errate.

5. I dati di Permalink Manager

Controllare eventualmente:

permalink-manager
permalink-manager-uris
permalink-manager-redirects
permalink-manager-external-redirects

all’interno di wp_options.

Il codice corrente del plugin conferma che queste informazioni vengono caricate da specifiche option WordPress.

6. Disattivare temporaneamente Permalink Manager

È il test che, nel mio caso, ha permesso di individuare immediatamente il responsabile.

Se:

Permalink Manager attivo  → 200
Permalink Manager spento  → 404

conviene smettere di cercare uno slug duplicato dentro WPML e concentrarsi sulla logica di routing di Permalink Manager.

7. Controllare “WPML/Polylang fix language mismatch”

Questo è stato il punto decisivo nel mio caso.

Conclusione

Il problema sembrava inizialmente causato da uno slug duplicato salvato da WPML o da Permalink Manager.

In realtà non esisteva nessun secondo permalink associato alla pagina inglese.

Era Permalink Manager che, riconoscendo lo slug appartenente alla pagina francese e trovandosi all’interno della directory /pl/, utilizzava WPML per recuperare automaticamente la relativa traduzione inglese.

Per questo:

/en/comment-lancer-une-boutique-de-reductions-en-ligne/

riusciva a mostrare:

/en/how-to-start-an-online-discount-store/

pur mantenendo il primo URL nella barra del browser.

L’impostazione che ha risolto definitivamente il problema è stata:

WPML/Polylang fix language mismatch → Redirect to the language variant of the requested page

Il caso dimostra anche quanto sia importante, quando si analizzano problemi di permalink su WordPress, non limitarsi a cercare URL e slug nel database.

Plugin come Permalink Manager possono infatti risolvere dinamicamente una richiesta e modificare il contenuto caricato in base alla lingua, rendendo apparentemente valido un URL che in WordPress, tecnicamente, non esiste.

FAQ

Perché WPML mostra la stessa pagina con due slug diversi?

Non è necessariamente WPML a memorizzare due slug. Se è presente Permalink Manager, il plugin può riconoscere uno slug appartenente a un’altra lingua e utilizzare WPML per caricare la traduzione corrispondente.

Perché non trovo il secondo slug nel database?

Perché l’URL potrebbe non essere memorizzato. Permalink Manager può interpretarlo dinamicamente durante la richiesta.

Perché entrambi gli URL restituiscono HTTP 200?

Se Permalink Manager è configurato per caricare automaticamente la variante linguistica della pagina richiesta, può trasformare internamente una richiesta relativa a una lingua nella traduzione corretta senza modificare l’URL nel browser.

Il canonical è sufficiente per evitare contenuti duplicati?

Il canonical aiuta i motori di ricerca a identificare l’URL preferito, ma quando un URL alternativo non deve realmente essere accessibile è generalmente più pulito utilizzare un redirect permanente verso quello corretto.

Quale impostazione di Permalink Manager bisogna controllare?

In presenza di WPML o Polylang bisogna verificare soprattutto l’opzione:

WPML/Polylang fix language mismatch

Se un URL con lo slug di un’altra lingua viene caricato con status 200, è particolarmente importante controllare se è impostata la modalità che carica direttamente la variante linguistica.

Come posso capire velocemente se il problema è Permalink Manager?

Disattiva temporaneamente il plugin e prova nuovamente l’URL anomalo.

Se passa da:

HTTP 200

a:

HTTP 404

hai un’indicazione molto forte che la risoluzione alternativa dell’URL dipenda da Permalink Manager.

Richiedi informazioni

Raccontami il tuo progetto, tracking, accessibilità, campagne adv da sistemare o semplicemente un sito che non vuol saperne di funzionare. Insieme possiamo migliorarlo.

    Accetto la Privacy Policy
    Autorizzo al trattamento dei miei dati personali, per ricevere le informazioni richieste attraverso questo modulo di contatto. I dati da te inseriti attraverso questo modulo verranno utilizzati solo per essere da me ricontattato.

    Recensioni

    Pubblicato su Google Google
    Flavio Corò profile picture
    Flavio Corò
    22/09/2023
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Ho avuto il piacere di contattare la Sig.ra Sara tramite suggerimento da parte di un mio cliente per riisolvere una pratica burocratica/lavorativa e devo dire che la VELOCITÀ, PROFESSIONALITÀ, e COMPETENZA fanno parte del Suo bagaglio lavorativo,qualita al giorno d'oggi per niente scontate.Pienamente soddisfatto.
    Pubblicato su Google Google
    Sonico Beauty profile picture
    Sonico Beauty
    17/01/2023
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Sara ci ha aiutato a risolvere piu' problemi in pochi minuti e con molta professionalità. Massima disponibilità e grande conoscenza nel mondo web. Assolutamente consigliata. Grazie mille
    Pubblicato su Google Google
    Studio Legale Avvocato Armando Baffioni Venturi profile picture
    Studio Legale Avvocato Armando Baffioni Venturi
    07/11/2022
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Contattata tramite il suo sito web si è rivelata una persona affabile e preparata, pronta nel recepire le mie necessità e nel darmi le indicazioni corrette da seguire. Assolutamente da consigliare anche per assistenze e consulenze da remoto.
    Pubblicato su Google Google
    Hermann Gils profile picture
    Hermann Gils
    28/10/2022
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Molto esperta, preparata e competente!
    Pubblicato su Google Google
    Antonio Cimadomo profile picture
    Antonio Cimadomo
    07/08/2022
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Definire La Sig.a Sara Gasparini persona capace, Umile, molto intelligente e disponibile è il minimo che si possa fare. E' stata una grande emozione per me averla 'scovata'. Persone come Sara alzano, e di tanto, il livello sociale/culturale. Ringrazio ancora Sara per esserci.... Antonio p.s. Peccato ci siano solo 5 stelle :-(
    Pubblicato su Google Google
    Max R_DJ profile picture
    Max R_DJ
    16/06/2021
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Molto professionale e preparata, ha risolto subito un mio problema inerente alle recensioni Google sul mio sito web. Complimenti Sara!
    Pubblicato su Google Google
    Fabrizio Aureli profile picture
    Fabrizio Aureli
    18/03/2021
    Google star 1Google star 2Google star 3Google star 4Google star 5Trustindex verifica che la fonte originale della recensione sia Google.
    Ottima collaboratrice

    Scrivimi una recensione

    Questo QR Code ti permette di lasciarmi una recensione in maniera facile e veloce.

    Altrimenti usa il bottone qui sotto.

    Lascia una recensione su Google