Cómo hacer un sitio web multilingüe sin redireccionamiento

Creamos un selector de idioma en JavaScript

by Tibor Kopca Date: 22-04-2021 Javascript desarrollo web selector de idioma


Hoy, vamos a hablar de cómo implementar un simple selector de idioma en el sitio web estático o básico, sin necesidad de ningún backend o llamadas a la base de datos o redirección a otra página. Vamos a utilizar sólo JavaScript, sin PHP u otros lenguajes de programación.

Servir contenido HTML en varios idiomas es un gran tema. Para empezar, lo que vamos a hacer es básicamente modificar las clases HTML mediante JavaScript para cambiar la apariencia de elementos HTML específicos en la página.
Para poder demostrarlo, hemos elegido una página web sencilla de un portafolio.


Ahora mostramos cómo hacer versiones en varios idiomas en un sitio web básico y cómo cambiar el contenido con JavaScript sin ningún backend, con la ventaja añadida de ser ligero y rápido. Cuando seleccionamos un idioma en nuestro elemento de cabecera, todo el contenido que hemos preparado cambiará a ese idioma.

Language_selector_headerEN

Language_selector_headerES

Sin más retraso, entremos en materia.

Requisitos básicos


Seguramente para continuar, asumimos que los conocimientos de HTML, CSS y JavaScript pueden ser útiles.

Selectores de idioma en la cabecera

Digamos que tenemos una página sencilla con la cabecera, el cuerpo, etc. ya hechos, pero nos gustaría añadir opciones de idiomas. Primero creamos tres versiones de los idiomas que queremos tener >

<div class="languageContainer">
   <div id="eng" class="languages british"><a>english</a></div>
   <div id="esp" class="languages spain"><p>español</p></div>
   <div id="svk" class="languages slovak"><p>slovensky</p></div>
</div>
<nav class="menu">
   <a href="#about" class="eng" lang="en">About</a>
   <a href="#about" class="esp" lang="es">Acerca de</a>
   <a href="#about" class="svk" lang="sk">O mne</a>
 
   <a href="#work" class="eng" lang="en">My work</a>
   <a href="#work" class="esp" lang="es">Trabajos</a>
   <a href="#work" class="svk" lang="sk">Moja praca</a>
 
   <a href="#contact" class="eng" lang="en">Contact</a>
   <a href="#contact" class="esp" lang="es">Contacto</a>
   <a href="#contact" class="svk" lang="sk">Kontakt</a>
</nav>

Ahora describimos lo que hemos hecho. Creamos el contenedor <div> con una clase específica para contener y modificar visualmente su contenido por CSS(lo mostramos más adelante).


A continuación, tenemos 3 conjuntos de idiomas, cada uno tiene la clase language, de nuevo para CSS, las clases british, spain, slovak son para un conjunto de banderas que tomamos de Country Flags - A simple API to load any country flags.

También tenemos un atributo lang, que permitirá a los rastreadores de búsqueda saber que este contenido está en otro idioma, tratarán ese contenido de manera diferente, esto es para un mejor ranking.

El más importante es el atributo id, este sirve para la escucha de eventos - básicamente cuando el código JavaScript detecta que por ejemplo hemos hecho clic en uno de estos tres, ejecutará nuestro código.
CSS para el código HTML superior>

.languageContainer {
  display: flex;
  justify-content: end;
  overflow: visible;
  height: 3rem;
  font-size: small;
}
.languages {
  display:flex;
  align-items: center;
  margin:.2rem;
  padding: 0.5rem;
  color: #fff;
  cursor: pointer;
}
.languages::before {
  content: '';
  display: block;
  width: 32px;
  height: 32px;
}
.british::before{
  background:url("https://www.countryflags.io/gb/flat/32.png");
}
.spain::before{
  background:url("https://www.countryflags.io/es/flat/32.png");
}
.slovak::before{
  background:url("https://www.countryflags.io/sk/flat/32.png");
}

(Observe que con y la altura de los iconos en la clase languages::before se correlaciona con el tamaño de la imagen que hemos establecido en el URL)
(Nota2 : fijamos un bonito puntero - la mano se mostrará cuando movamos el cursor del ratón por encima de la clase languages)

Alternativamente, podemos usar imágenes descargadas (iconos), estas son de flagpedia.net, para estar seguros de que nuestra página no se colgará cuando la fuente externa no esté disponible. Así que lo hicimos local como esto>

.british::before{
  background:url('../img/flags/unitedkingdom32x32.png')
}
.spain::before{
  background:url('../img/flags/spain32x32.png')
}
.slovak::before{
  background:url('../img/flags/slovakia32x32.png')
}

Parte de JavaScript

Ahora la parte de codificación. Necesitaríamos manipular la aparición o desaparición de esos elementos con diferentes textos. Para acceder a ellos, en nuestro archivo JavaScript creamos >

const selectedEnglish = document.getElementById("eng");
const selectedEspanol = document.getElementById("esp");
const selectedSlovensky = document.getElementById("svk");
const hidden = "display:none;";
const shown = "display:block;";

Las variables hidden y shown modificarán el estilo del elemento HTML desde este script.
Para acceder a todos los elementos con el mismo idioma, creamos este código>

const allEnglishText = document.getElementsByClassName("eng");
const allEspanolText = document.getElementsByClassName("esp");
const allSlovakText = document.getElementsByClassName("svk");

Ahora tenemos que reconocer lo que vamos a hacer con él. Necesitamos encender la versión de un idioma y al mismo tiempo apagar todas las demás versiones.
Esto se puede poner en la función, y tenemos que tener 3 funciones para cada versión de idioma. Por ejemplo :
allEnglishText es una colección de todos los elementos HTML con el mismo nombre de clase eng . En la función, recorremos todos esos elementos y establecemos el parámetro, o digamos el estilo a todos ellos, y de la misma manera, todas las otras versiones de idioma no se mostrarán en absoluto.

//SHOW ALL ENGLISH TEXT
function showEnglishText() {
  for (element in allEnglishText) {
     allEnglishText[element].style = shown;
  }
  for (element in allEspanolText) {
    allEspanolText[element].style = hidden;
  }
  for (element in allSlovakText) {
    allSlovakText[element].style = hidden;
  }
}
//SHOW ALL SPANISH TEXT
function showSpanishText() {
  for (element in allEnglishText) {
    allEnglishText[element].style = hidden;
  }
  for (element in allEspanolText) {
    allEspanolText[element].style = shown;
  }
  for (element in allSlovakText) {
    allSlovakText[element].style = hidden;
  }
}
//SHOW ALL SLOVAK TEXT
function showSlovakText() {
  for (element in allEnglishText) {
    allEnglishText[element].style = hidden;
  }
  for (element in allEspanolText) {
    allEspanolText[element].style = hidden;
  }
  for (element in allSlovakText) {
    allSlovakText[element].style = shown;
  }
}

Botones y EventListeners


Hasta ahora hemos creado todo el texto en HTML y las funciones para mostrarlas u ocultarlas, pero también necesitamos el switch para lanzar las funciones. Seguimos detrás del código anterior añadiendo esto>

//ENGLISH-> ALL OTHERS SWITCHED OFF
selectedEnglish.addEventListener("click", () => {
  selectedEnglish.classList.add("langSelected");
  selectedEspanol.classList.remove("langSelected");
  selectedSlovensky.classList.remove("langSelected");
 
  showEnglishText();
});

Para explicarlo, añadiendo un escuchador de eventos en el elemento almacenado en la variable selectedEnglish --> ese es nuestro elemento en la cabecera con id=’eng’ , cuando hagamos clic en él con el ratón, se lanzará nuestra función showEnglishText() y además tenemos un montón de código para añadirle una clase CSS, que contenga borde, para mostrar visualmente qué botón se ha pulsado en ese momento.
Por supuesto, tenemos que añadir todas las demás versiones>

//SPANISH-> ALL OTHERS SWITCHED OFF
selectedEspanol.addEventListener("click", () => {
  selectedEspanol.classList.add("langSelected");
  selectedEnglish.classList.remove("langSelected");
  selectedSlovensky.classList.remove("langSelected");
 
  showSpanishText();
});
 
//SLOVAK-> ALL OTHERS SWITCHED OFF
selectedSlovensky.addEventListener("click", () => {
  selectedSlovensky.classList.add("langSelected");
  selectedEspanol.classList.remove("langSelected");
  selectedEnglish.classList.remove("langSelected");
 
  showSlovakText();
});

Esto por sí solo sería suficiente para que funcione, pero hay un pequeño problema, hasta ahora seguimos viendo las 3 versiones por defecto, sólo después de hacer clic en el botón respectivo, se ocultan. Así que tenemos que asegurarnos de que por defecto sólo hay 1 visible llamando por ejemplo a la función showEnglishText() detrás de la definición de las variables. Pero podemos mejorarlo como veremos en el próximo capítulo.


Mecanismo para almacenar el idioma seleccionado en el almacenamiento local(Local Storage)

Ahora daremos un paso más y almacenaremos el idioma elegido en el Local Storage del navegador del usuario. De esta manera, se le servirá al usuario el idioma que seleccionó por última vez. Esto significa que incluso si la página se actualiza, "recordará" la última selección. Creamos una entrada en el almacenamiento local utilizando localStorage.setItem() en cada uno de los escuchadores de eventos, así>

//ENGLISH-> ALL OTHERS SWITCHED OFF
selectedEnglish.addEventListener("click", () => {
  selectedEnglish.classList.add("langSelected");
  selectedEspanol.classList.remove("langSelected");
  selectedSlovensky.classList.remove("langSelected");
 
  showEnglishText();
  localStorage.setItem("languageActive", "english");
});
 
//SPANISH-> ALL OTHERS SWITCHED OFF
selectedEspanol.addEventListener("click", () => {
  selectedEspanol.classList.add("langSelected");
  selectedEnglish.classList.remove("langSelected");
  selectedSlovensky.classList.remove("langSelected");
 
  showSpanishText();
  localStorage.setItem("languageActive", "espanol");
});
 
//SLOVAK-> ALL OTHERS SWITCHED OFF
selectedSlovensky.addEventListener("click", () => {
  selectedSlovensky.classList.add("langSelected");
  selectedEspanol.classList.remove("langSelected");
  selectedEnglish.classList.remove("langSelected");
 
  showSlovakText();
  localStorage.setItem("languageActive", "slovak");
});

De esta forma tendremos almacenado bajo el id languageActive la versión del idioma que acabamos de pulsar. Ahora es el momento de escribir el código para recuperar esta información del almacenamiento local. Y así es como>

//LOCAL STORAGE ADDON
switch (localStorage.getItem("languageActive")) {
 
    case "english":
      selectedEnglish.classList.add("langSelected");
      showEnglishText();
      break;
 
    case "espanol":
      selectedEspanol.classList.add("langSelected");
      showSpanishText();
      break;
 
    case "slovak":
      selectedSlovensky.classList.add("langSelected");
      //console.log("slovak on");
      showSlovakText();
      break;
 
    default:
      //default ENGLISH text shown, all others disabled
//default -> no local storage exists
      selectedEnglish.classList.add("langSelected");
      showEnglishText();
  }

Por defecto - si no pudimos recuperar nada del Almacenamiento Local, por ejemplo, el usuario es la primera vez en su sitio, se lanzará el código default . Elegimos el inglés para que se muestre primero.
Cuando hay una entrada encontrada, switch reconocerá el valor y llamará a la función respectiva.

Language_selector_localStorage

Language_selector_FinalShowcase

Conclusión

Os hemos mostrado cómo hacer un cambio de idioma muy básico y esperamos que os haya gustado.

Lo mejor sería hacer saber al buscador que tenemos versiones localizadas del texto en nuestra página, para que no traten el texto traducido como duplicado. Porque eso puede llevar a un montón de contenido aplicado y eso a su vez puede llevar a un ranking más bajo en los motores de búsqueda.

Seguramente podemos mejorar esto, por ejemplo poniendo todo el contenido del texto (todas las traducciones también) en un objeto y seleccionando la versión deseada del texto desde él con un código que recupere el valor de la clave, pero eso lo haremos en otro artículo. Hasta pronto.


Imágenes de Tibor Kopca

 
by Tibor Kopca Date: 22-04-2021 Javascript desarrollo web selector de idioma visitas : 579  
 
Tibor Kopca

Tibor Kopca

From tinkering with computers as a teenager, through a career in datacenter he stepped into web development with full force and started coding. Absorbs all information like a sponge.
Fan of aerospace, engineering, information technologies and watches.

 
 
 

Artículos relacionados

Cómo enviar un correo electrónico desde un formulario de contacto HTML

En el artículo de hoy vamos a escribir sobre cómo hacer un formulario que funcione y que al pulsar ese botón de envío sea funcional y envíe el correo electrónico…

Comenzando con Bootstrap-Vue paso a paso

Hoy te mostraremos cómo usar BootstrapVue, describiremos el proceso de instalación y mostraremos la funcionalidad básica. El proyecto está basado en el framework CSS más popular del mundo - Bootstrap, para…

Por qué los desarrolladores de JavaScript deberían preferir Axios a Fetch

Por qué los desarrolladores de JavaScript deberían preferir Axios a Fetch En mi artículo anterior, "Usando la Api Fetch Para Hacer Llamadas Ajax", hablé de los fundamentos de la API Fetch.…

Creación de un sencillo spinner-loader CSS

En el artículo de hoy mostraremos cómo animar un loader básico que gira cuando se define alguna acción predefinida, como cargar una imagen. Eso se puede utilizar en un sitio…

Los mejores selectores de fechas para Bootstrap y tu aplicación

Los selectores de fecha son widgets que permiten a los usuarios elegir una sola fecha o rango de fechas y horas. Es un elemento habitual para todo usuario de Internet,…

Validación de formularios HTML usando BULMA y vanilla JavaScript

Hoy vamos a escribir sobre los formularios de contacto y cómo validarlos usando JavaScript. El formulario de contacto parece ser una de las características principales de toda página web básica. Es…

Cómo usar el efecto Parallax.Js en tu sitio web

Hoy vamos a escribir sobre el efecto de parallax, similar al desplazamiento de parallax, y cómo implementarlo para mejorar su página de aterrizaje. En webdev, dicen que primero el móvil…

Usando la API FETCH para hacer llamadas AJAX - Una promesa cumplida

En este artículo hablamos sobre lo que son las llamadas AJAX y cómo utilizarlas de forma tradicional, utilizando el objeto XMLHttpRequest (XHR). En resumen, gracias a las llamadas AJAX una…

Modo oscuro persistente con CSS y JS

Recientemente escribimos acerca de cómo hacer un modo de color o tema alternativo intercambiable, una característica muy útil y popular para los sitios web. El artículo de hoy tratará sobre…

Modo oscuro en el sitio web usando CSS y JavaScript

En el artículo de hoy vamos a aprender a construir más o menos estándar en estos días en las páginas web y que es el modo de color alternativo y…

Javascript: los operadores Spread y Rest

En el artículo de hoy vamos a hablar de una de las características de la versión ES6 (ECMAScript 2015) de JavaScript que es el operador Spreadasí como el operador Rest. Estas…

Cookies HTTP: cómo funcionan y cómo usarlas

Hoy vamos a escribir sobre la forma de almacenar datos en un navegador, por qué los sitios web utilizan cookies y cómo funcionan en detalle. Continúa leyendo para averiguar cómo implementarlas…

Utilizamos cookies propias y de terceros para mejorar nuestros servicios, elaborar información estadística y analizar tus hábitos de navegación. Esto nos permite personalizar el contenido que ofrecemos y mostrarte publicidad relacionada con tus preferencias. Clicando en ‘Acepta todas’ aceptas el almacenamiento de cookies en tu dispositivo para mejorar la navegación en el sitio web, analizar el tráfico y ayudar en nuestras actividades de marketing. También puedes seleccionar ‘Sólo cookies de sistema’ para aceptar sólo las cookies necesarias para que la web funcione, o puedes seleccionar las cookies que quieres activar clicando en ‘Configuración’

Acepta todas Sólo cookies de sistema Configuración