Comprende los aspectos básicos de JavaScript SEO

JavaScript es una parte importante de la plataforma web porque proporciona muchas funciones que convierten a la Web en una potente plataforma de apps. Permitir que tus aplicaciones web con tecnología JavaScript sean detectables por medio de la Búsqueda de Google puede ayudarte a encontrar usuarios nuevos y volver a captar el interés de los existentes cuando buscan el contenido que proporciona tu aplicación web. Si bien la Búsqueda de Google ejecuta JavaScript con una versión de Chromium perdurable, hay algunas funciones que puedes optimizar.

En esta guía, se explica cómo la Búsqueda de Google procesa JavaScript y se describen las prácticas recomendadas de optimización de aplicaciones web con JavaScript para la Búsqueda de Google.

Cómo el robot de Google procesa JavaScript

Googlebot procesa las aplicaciones web con JavaScript en tres fases principales:

  1. Rastreo
  2. Procesamiento
  3. Indexación

El robot de Google rastrea, procesa y, por último, indexa una página.

El robot de Google toma una URL de la cola de rastreo y, luego, la transmite a la etapa de procesamiento. En esta etapa, se extraen los vínculos que remiten a la cola de rastreo y se pone la página en cola para su procesamiento. La página pasa de la cola de procesamiento al procesador, que devuelve el HTML procesado a la etapa de procesamiento, en la que se indexa el contenido y se extraen los vínculos a fin de colocarlos en la cola de rastreo.

Cuando el robot de Google obtiene una URL de la cola de rastreo mediante una solicitud HTTP, primero verifica si permites el rastreo. Para ello, lee el archivo robots.txt. Si la URL se marcó como no permitida, entonces el robot de Google no envía la solicitud HTTP para esta URL y la omite.

Luego, el robot de Google analiza la respuesta de las otras URL en el atributo href de los vínculos HTML y agrega las URL a la cola de rastreo. Para evitar la detección de vínculos, usa el mecanismo nofollow.

El rastreo de una URL y el procesamiento de la respuesta HTML funcionan bien para los sitios web clásicos o las páginas procesadas por el servidor, en las que el HTML de la respuesta HTTP incluye todo el contenido. Algunos sitios de JavaScript pueden usar el modelo de shell de la app donde el HTML inicial no incluye el contenido real y el robot de Google necesita ejecutar JavaScript para poder ver el contenido real de la página generado por JavaScript.

El robot de Google pone en cola todas las páginas para su procesamiento, a menos que un encabezado o una metaetiqueta robots le indique que no indexe la página. La página puede permanecer en esta cola durante unos segundos, pero podría tardar más. Una vez que los recursos del robot de Google lo permiten, un Chromium sin interfaz gráfica procesa la página y ejecuta el JavaScript. El robot de Google vuelve a analizar el HTML procesado para los vínculos y pone en cola las URL que encuentra para rastrear. También usa el HTML procesado para indexar la página.

Ten en cuenta que el procesamiento previo o del servidor sigue siendo una buena opción, ya que hace que el sitio web funcione más rápido para los usuarios y los rastreadores, y no todos los bots pueden ejecutar JavaScript.

Describe tu página con títulos y fragmentos únicos

Los títulos únicos y descriptivos, así como las metadescripciones, ayudan a los usuarios a identificar rápidamente el mejor resultado para su propósito. Consulta cómo crear títulos y descripciones interesantes en nuestros lineamientos.

Puedes usar JavaScript para establecer o cambiar la metadescripción y el título.

Escribe código compatible

Los navegadores ofrecen muchas API y JavaScript es un lenguaje que evoluciona rápidamente. El robot de Google tiene algunas limitaciones con respecto a las API y las funciones de JavaScript que admite. Para asegurarte de que tu código sea compatible con el robot de Google, sigue nuestros lineamientos de solución de problemas de JavaScript.

Usa códigos de estado HTTP significativos

El robot de Google usa códigos de estado HTTP para detectar si se produjo algún error al rastrear la página.

Debes usar un código de estado significativo para indicarle al robot de Google si una página no se debe rastrear o indexar, como un código 404 para una página que no se pudo encontrar o 401 para páginas que requieren acceso. Puedes usar los códigos de estado HTTP para indicarle al robot de Google si una página se movió a una nueva URL, de manera que se pueda actualizar correctamente el índice.

A continuación, se muestra una lista de códigos de estado HTTP y cuándo usarlos:

Estado HTTP Cuándo debe utilizarse
301/302 Se movió la página a una nueva URL.
401/403 La página no está disponible debido a problemas con los permisos.
404/410 La página ya no está disponible.
5xx Se produjo un error en el servidor.

Evita errores leves 404 en apps de una sola página

En las apps de una sola página procesadas por el cliente, el enrutamiento se suele implementar como enrutamiento del cliente. En este caso, el uso de códigos de estado HTTP significativos puede ser imposible o poco práctico. Para evitar los errores leves 404 cuando usas el procesamiento y el enrutamiento del cliente, utiliza una de las siguientes estrategias:

  • Usa un redireccionamiento de JavaScript a una URL a la que el servidor responde con un código de estado HTTP 404 (por ejemplo, /not-found).
  • Agrega un elemento <meta name="robots" content="noindex"> a las páginas de error con JavaScript.

Este es un código de muestra para el enfoque de redireccionamiento:

fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
  if(product.exists) {
    showProductDetails(product); // shows the product information on the page
  } else {
    // this product does not exist, so this is an error page.
    window.location.href = '/not-found'; // redirect to 404 page on the server.
  }
})

Este es un código de muestra para el enfoque noindex:

fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
  if(product.exists) {
    showProductDetails(product); // shows the product information on the page
  } else {
    // this product does not exist, so this is an error page.
    // Note: This example assumes there is no other meta robots tag present in the HTML.
    const metaRobots = document.createElement('meta');
    metaRobots.name = 'robots';
    metaRobots.content = 'noindex';
    document.head.appendChild(metaRobots);
  }
})

Usa la History API en lugar de fragmentos

Cuando Googlebot busca vínculos en tus páginas, solo considera las URL en el atributo href de los vínculos HTML.

En el caso de aplicaciones de una sola página con enrutamiento del cliente, usa la History API para implementar el enrutamiento entre diferentes vistas de tu aplicación web. Evita utilizar fragmentos para cargar contenido de páginas diferentes si quieres asegurarte de que Googlebot pueda encontrar los vínculos. En el siguiente ejemplo, se muestra una práctica no recomendada, ya que Googlebot no rastreará los vínculos:

<nav>
  <ul>
    <li><a href="#/products">Our products</a></li>
    <li><a href="#/services">Our services</a></li>
  </ul>
</nav>

<h1>Welcome to example.com!</h1>
<div id="placeholder">
  <p>Learn more about <a href="#/products">our products</a> and <a href="#/services">our services</p>
</div>
<script>
window.addEventListener('hashchange', function goToPage() {
  // this function loads different content based on the current URL fragment
  const pageToLoad = window.location.hash.slice(1); // URL fragment
  document.getElementById('placeholder').innerHTML = load(pageToLoad);
});
</script>

En su lugar, puedes asegurarte de que Googlebot pueda acceder a las URL del vínculo mediante la implementación de la History API:

<nav>
  <ul>
    <li><a href="/products">Our products</a></li>
    <li><a href="/services">Our services</a></li>
  </ul>
</nav>

<h1>Welcome to example.com!</h1>
<div id="placeholder">
  <p>Learn more about <a href="/products">our products</a> and <a href="/services">our services</p>
</div>
<script>
function goToPage(event) {
  event.preventDefault(); // stop the browser from navigating to the destination URL.
  const hrefUrl = event.target.getAttribute('href');
  const pageToLoad = hrefUrl.slice(1); // remove the leading slash
  document.getElementById('placeholder').innerHTML = load(pageToLoad);
  window.history.pushState({}, window.title, hrefUrl) // Update URL as well as browser history.
}

// Enable client-side routing for all links on the page
document.querySelectorAll('a').forEach(link => link.addEventListener('click', goToPage));

</script>

Usa las metaetiquetas robots cuidadosamente

Puedes impedir que el robot de Google indexe una página o acceda a vínculos mediante la metaetiqueta robots. Por ejemplo, si agregas la siguiente metaetiqueta en la parte superior de tu página, impedirás que el robot de Google la indexe:

<!-- Googlebot won't index this page or follow links on this page -->
<meta name="robots" content="noindex, nofollow">

Puedes usar JavaScript para agregar una metaetiqueta robots a una página o cambiar su contenido. El siguiente código de ejemplo muestra cómo cambiar la metaetiqueta robots con JavaScript para evitar la indexación de la página actual si una llamada a la API no muestra contenido.

fetch('/api/products/' + productId)
  .then(function (response) { return response.json(); })
  .then(function (apiResponse) {
    if (apiResponse.isError) {
      // get the robots meta tag
      var metaRobots = document.querySelector('meta[name="robots"]');
      // if there was no robots meta tag, add one
      if (!metaRobots) {
        metaRobots = document.createElement('meta');
        metaRobots.setAttribute('name', 'robots');
        document.head.appendChild(metaRobots);
      }
      // tell Googlebot to exclude this page from the index
      metaRobots.setAttribute('content', 'noindex');
      // display an error message to the user
      errorMsg.textContent = 'This product is no longer available';
      return;
    }
    // display product information
    // ...
  });
    

Cuando el robot de Google encuentra noindex en la metaetiqueta robots, no procesa ni indexa la página.

Usa el almacenamiento en caché de larga duración

Googlebot almacena en caché de forma resolutiva para reducir las solicitudes de red y el uso de recursos. WRS puede ignorar los encabezados de almacenamiento en caché. Como consecuencia, es posible que WRS use recursos JavaScript o CSS desactualizados. La huella digital de contenido evita este problema porque crea una huella digital de la parte de contenido del nombre del archivo, como main.2bb85551.js. La huella digital depende del contenido del archivo, por lo que cada vez que se lanza una actualización se genera un nombre de archivo diferente. Consulta la guía de web.dev sobre estrategias de almacenamiento en caché de larga duración para obtener más información.

Utiliza datos estructurados

Cuando usas datos estructurados en tus páginas, puedes usar JavaScript para generar el archivo JSON-LD necesario e insertarlo en la página. Asegúrate de probar la implementación para evitar problemas.

Sigue las prácticas recomendadas para componentes web

Googlebot admite componentes web. Cuando Googlebot procesa una página, acopla el contenido del shadow DOM y del light DOM. Esto significa que el robot de Google solo puede ver el contenido que está visible en el HTML procesado. Para asegurarte de que el robot de Google pueda ver tu contenido después de procesarlo, usa la prueba de optimización o la Herramienta de inspección de URL y observa el HTML procesado.

Si el contenido no es visible en el HTML procesado, el robot de Google no podrá indexarlo.

En el siguiente ejemplo, se crea un componente web que muestra su contenido de light DOM dentro de su shadow DOM. Una forma de asegurarse de que tanto el contenido del light DOM como del shadow DOM se muestre en el HTML procesado es utilizar un elemento slot.

<script>
  class MyComponent extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
    }

    connectedCallback() {
      let p = document.createElement('p');
      p.innerHTML = 'Hello World, this is shadow DOM content. Here comes the light DOM: <slot></slot>';
      this.shadowRoot.appendChild(p);
    }
  }

  window.customElements.define('my-component', MyComponent);
</script>

<my-component>
  <p>This is light DOM content. It's projected into the shadow DOM.</p>
  <p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>
            

Después del procesamiento, Googlebot indexará este contenido:

<my-component>
  Hello World, this is shadow DOM content. Here comes the light DOM:
  <p>This is light DOM content. It's projected into the shadow DOM<p>
  <p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>
    

Soluciona los problemas con las imágenes y el contenido de carga diferida

Las imágenes pueden consumir mucho ancho de banda y rendimiento. Una buena estrategia es utilizar la carga diferida para cargar imágenes solo cuando el usuario esté a punto de verlas. Para asegurarte de que estás implementando una carga diferida que sea fácil de buscar, sigue nuestros lineamientos de carga diferida.