Tu sitio multilingüe probablemente solo está indexado en un idioma
Cambiar de idioma con JavaScript en una sola URL es la forma más común de volver invisibles seis traducciones para los buscadores. Qué se indexa realmente y cómo estructurar un sitio estático para que no pase.
Un patrón que vemos a menudo: una empresa traduce su web a seis idiomas, publica un selector de idioma y no ve tráfico de ninguno de los mercados nuevos. Las traducciones son buenas. Nadie las encuentra.
La causa es casi siempre la misma, y es arquitectónica, no editorial.
Los buscadores indexan URLs, no estado de aplicación
Si tu selector de idioma cambia el texto de la página y recuerda la elección en localStorage o una cookie, todos los idiomas comparten una URL.
El rastreador pide esa URL, recibe el idioma que venga horneado en el HTML y lo indexa. Tus otras seis traducciones no existen para el buscador. No hay una segunda URL que posicionar, ni título propio, ni descripción propia.
No es una limitación del rastreador que haya que sortear. La URL es la unidad de indexación. Una URL significa un documento indexado.
La prueba es simple: ¿puedes enviarle a alguien un enlace que abra tu página en japonés? Si no, Google tampoco puede indexar una versión en japonés.
Para qué sí sirve el cambio en cliente
Conviene ser justos con el patrón, porque no siempre está mal. El cambio en cliente es perfectamente razonable cuando la página no es algo que la gente encuentre por su texto:
- Interfaces de aplicación tras un login
- Paneles y herramientas internas
- Una web pequeña cuyo tráfico viene de anuncios, referencias o boca a boca
Se convierte en problema en cuanto quieres tráfico orgánico en esos idiomas. El marketing de contenidos, la documentación y los blogs son exactamente ese caso.
Dale a cada idioma una URL real
Tres estructuras habituales, todas aceptables para los buscadores:
| Estructura | Ejemplo | Notas |
|---|---|---|
| Subdirectorio | example.com/ja/page | La más simple. Hereda la autoridad del dominio. Suele ser lo correcto. |
| Subdominio | ja.example.com/page | Viable, con más gestión de DNS y certificados. |
| Dominio aparte | example.jp/page | Señal local más fuerte, coste mayor. Cada dominio acumula autoridad por su cuenta. |
Para la mayoría de equipos, subdirectorios. Tienes un dominio acumulando autoridad y ningún trabajo de infraestructura.
Después, dile al buscador que esas páginas están relacionadas
Separar las URLs crea un riesgo nuevo: siete páginas que dicen lo mismo pueden parecer contenido duplicado. hreflang es cómo dices «estas son la misma página en distintos idiomas, muestra la correcta».
En cada versión, lista todas las versiones, incluida ella misma:
<link rel="alternate" hreflang="en" href="https://example.com/en/page">
<link rel="alternate" hreflang="vi" href="https://example.com/vi/page">
<link rel="alternate" hreflang="ja" href="https://example.com/ja/page">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page">
Más un canonical autorreferencial en cada una:
<link rel="canonical" href="https://example.com/ja/page">
Los cinco errores que lo rompen
- Faltan enlaces de vuelta.
hreflangdebe ser recíproco. Si la página inglesa apunta a la japonesa y la japonesa no devuelve el apuntado, el emparejamiento se ignora. Es, con diferencia, el fallo más común. - Canonical apuntando a otro idioma. Una página japonesa cuyo canonical apunta a la URL inglesa está indicando al buscador que la descarte. El canonical debe apuntar a sí misma.
- Confundir idioma y región.
hreflang="ja"es el idioma japonés.hreflang="ja-JP"es japonés específicamente para Japón. Usa el código de idioma a secas salvo que tengas de verdad variantes por región; estrechar sin necesidad te cuesta lectores en otros sitios. - Códigos incorrectos. La subetiqueta de región es un código de país, no de idioma. El inglés británico es
en-GB, noen-UK. Para el chino importa más la escritura que el país:zh-Hansyzh-Hant. - URLs relativas.
hreflangy canonical quieren URLs absolutas con protocolo y dominio.
Traduce también los slugs
Una ganancia fácil que se salta mucha gente: las palabras de la URL son una señal de relevancia en ese idioma. Si tu página en vietnamita vive en /vi/how-to-look-up-a-character, la URL no aporta nada en vietnamita.
Traduce el slug y mantén un identificador interno estable para emparejar las versiones. Así estructuramos exactamente este blog: cada artículo tiene un id que nunca cambia y un slug por idioma que sí.
No redirijas automáticamente por IP
Es tentador y hace daño real. Si detectas el país del visitante y fuerzas una redirección:
- Los rastreadores piden mayoritariamente desde un país y pueden acabar viendo una sola versión.
- Anulas a quien eligió otra cosa a propósito. Mucha gente en Japón quiere leer en inglés.
Sugiere, no fuerces. Ofrece un aviso, mantén el selector visible y deja que la URL decida el contenido.
Los sitios estáticos lo ponen fácil
Nada de esto necesita CMS ni servidor. Genera un archivo HTML por idioma y por página en tiempo de compilación, con las etiquetas correctas horneadas, y sube la carpeta. La salida son archivos estáticos; la inteligencia está en el generador que ejecutas antes de desplegar.
Es lo que hacemos con este blog: el contenido vive en un archivo por artículo y por idioma, un script pequeño emite el HTML con hreflang, canonical, JSON-LD y entradas de sitemap por idioma, y el sitio sigue siendo una carpeta de archivos estáticos sin backend alguno.
Una lista de comprobación
- Cada idioma tiene su propia URL que puedes enviar a alguien
- Cada página lista todos los idiomas en
hreflang, incluida ella misma, de forma recíproca - Existe un
x-defaultpara visitantes sin coincidencia - El canonical de cada página apunta a sí misma
- Los slugs están traducidos, con un id estable emparejándolos por dentro
- El sitemap lista cada URL de idioma con sus alternativas
html langcoincide con el contenido real- No hay redirecciones forzadas por IP