Princípios básicos de SEO em JavaScript

O JavaScript é uma parte importante da plataforma da Web porque conta com muitos recursos que a transformam em uma plataforma eficiente para aplicativos. Fazer com que os aplicativos da Web com tecnologia JavaScript possam ser detectados pela Pesquisa Google é importante para encontrar novos usuários e recuperar o engajamento dos existentes quando eles pesquisarem o conteúdo oferecido pelo seu aplicativo. Embora a Pesquisa Google execute JavaScript com uma versão contínua do Chromium, há algumas coisas que você pode otimizar.

Este guia descreve como a Pesquisa Google processa o JavaScript e indica práticas recomendadas de melhoria dos apps da Web JavaScript para a Pesquisa Google.

Como o Googlebot processa JavaScript

O Googlebot processa apps da Web JavaScript em três fases principais:

  1. Rastreamento
  2. Renderização
  3. Indexação

O Googlebot rastreia, renderiza e indexa as páginas.

O Googlebot pega um URL da fila de rastreamento,
       o rastreia e o passa para a etapa de processamento. A etapa de processamento extrai os links, que
       voltam à fila de rastreamento, e coloca a página na fila de renderização. A página vai da fila para o
       renderizador, que devolve o HTML renderizado para o processamento. Então o conteúdo é indexado,
       e os links são extraídos e adicionados à fila de rastreamento.

Quando o Googlebot busca um URL da fila de rastreamento por meio de uma solicitação HTTP, primeiro ele verifica se você permite o rastreamento. O Googlebot lê o arquivo robots.txt. Quando ele marca o URL como não permitido, o Googlebot pula a solicitação HTTP desse URL e o ignora.

Depois o Googlebot analisa a resposta de outros URLs no atributo href dos links HTML e os adiciona à fila de rastreamento. Para impedir que links sejam detectados, use o mecanismo nofollow.

Rastrear um URL e analisar a resposta HTML funciona bem para sites clássicos ou páginas renderizadas no servidor, em que o HTML na resposta HTTP inclui todo o conteúdo. Alguns sites JavaScript usam o modelo de shell do app, em que o HTML inicial não inclui o conteúdo em si, e o Googlebot precisa executar JavaScript para acessar os recursos da página que ele gera.

O Googlebot forma uma fila com todas as páginas a serem renderizadas, a menos que um cabeçalho ou metatag robots diga para não indexar a página. Ela pode ficar nessa fila por alguns segundos ou mais. Quando os recursos do Googlebot permitem, uma versão headless do Chromium renderiza a página e executa o JavaScript. O Googlebot analisa novamente o HTML renderizado em busca de links e forma uma fila com os URLs encontrados para rastreamento. Ele também usa o HTML renderizado para indexar a página.

A renderização prévia ou no servidor ainda é uma ótima ideia, porque deixa os sites mais rápidos para usuários e rastreadores, e nem todos os bots executam JavaScript.

Descreva sua página com títulos e snippets exclusivos

Os títulos descritivos e exclusivos e as metadescrições relevantes ajudam os usuários a identificar rapidamente o melhor resultado para os próprios objetivos. Explicamos como fazer bons títulos e descrições nas nossas diretrizes.

Você pode usar o JavaScript para definir ou alterar a metadescrição e o título.

Escreva código compatível

Os navegadores contam com muitas APIs, e o JavaScript é uma linguagem em rápida evolução. O Googlebot tem algumas limitações de compatibilidade com APIs e recursos JavaScript. Para garantir que seu código seja compatível com o Googlebot, siga nossas diretrizes para solução de problemas com JavaScript.

Use Códigos de status HTTP significativos

O Googlebot usa códigos de status HTTP para descobrir se algo deu errado ao rastrear a página.

Use um código de status significativo para informar ao Googlebot que o conteúdo não pode ser rastreado nem indexado, como 404 para páginas não encontradas ou 401 para aquelas protegidas por login. Você pode usar códigos de status HTTP para avisar ao Googlebot que uma página foi movida para um novo URL. Assim ele atualiza o índice.

Veja uma lista de Códigos de status HTTP e casos de uso:

Status HTTP Uso
301 / 302 A página foi movida para um novo URL.
401 / 403 A página não está disponível devido a problemas de permissão.
404 / 410 A página não está mais disponível.
5xx Ocorreu um erro no servidor.

Evite erros soft 404 em apps de página única

Em apps de página única renderizados no lado do cliente, o roteamento geralmente é implementado também no lado do cliente. Nesse caso, pode ser impossível ou impraticável usar códigos de status HTTP significativos. Para evitar erros soft 404 ao usar a renderização e o roteamento no lado cliente, use uma das seguintes estratégias:

  • Use um redirecionamento JavaScript para um URL a que o servidor responda com um código de status HTTP 404, como /not-found.
  • Use JavaScript para adicionar um <meta name="robots" content="noindex"> às páginas de erro.

Veja um exemplo de código para a abordagem de redirecionamento:

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.
  }
})

Veja um exemplo de código para a abordagem 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);
  }
})

Use a API History em vez de fragmentos

Quando o Googlebot procura links nas páginas, ele considera somente URLs no atributo href de links HTML.

Em apps de página única com roteamento no lado do cliente, use a API History para implementar o roteamento entre diferentes visualizações do seu app da Web. Para garantir que o Googlebot possa encontrar links, não use fragmentos para carregar diferentes conteúdos da página. O exemplo a seguir é uma prática não recomendada porque o Googlebot não rastreará os links:

<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>

Em vez disso, implemente a API History para verificar se os URLs de link são acessíveis ao Googlebot:

<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>

Use as metatags robots com cuidado

Você pode impedir que o Googlebot indexe uma página ou siga links por meio da metatag robots. Por exemplo, adicionar a seguinte metatag à parte superior da página impede que o Googlebot a indexe:

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

Você pode usar o JavaScript para adicionar uma metatag robots a uma página ou alterar o conteúdo correspondente. O código de exemplo a seguir mostra como alterar a metatag robots com JavaScript para impedir a indexação da página atual caso uma chamada de API não retorne o conteúdo.

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
    // ...
  });
    

Ao encontrar noindex na metatag robots antes de executar o JavaScript, o Googlebot não fará a renderização nem a indexação da página.

Use armazenamento em cache de longa duração

O Googlebot armazena muitos dados em cache para reduzir as solicitações de rede e o uso de recursos. O WRS pode ignorar cabeçalhos de armazenamento em cache. Talvez isso leve o WRS a usar recursos desatualizados de JavaScript ou CSS. A técnica de impressão digital de conteúdo evita esse problema ao criar uma referência à parte do nome do arquivo relativa ao conteúdo, como main.2bb85551.js. A impressão digital depende do conteúdo do documento. Por isso, cada atualização gera um nome de arquivo diferente. Consulte o guia web.dev sobre estratégias de armazenamento em cache de longa duração para saber mais.

Use dados estruturados

Ao utilizar dados estruturados nas suas páginas, use o JavaScript para gerar o JSON-LD exigido e injetá-lo na página. Teste sua implementação para evitar problemas.

Siga as práticas recomendadas para componentes da Web

O Googlebot é compatível com componentes da Web. Quando o Googlebot renderiza uma página, ele nivela o conteúdo shadow DOM e light DOM. Isso significa que o Googlebot só poderá visualizar o conteúdo que estiver visível no HTML renderizado. Para garantir que o Googlebot ainda possa ver seu conteúdo depois que ele for renderizado, use o Teste de compatibilidade com dispositivos móveis ou a Ferramenta de inspeção de URL e confira o HTML renderizado.

Se o conteúdo não estiver visível no HTML renderizado, o Googlebot não poderá indexá-lo.

O exemplo a seguir cria um componente da Web que exibe o conteúdo light DOM dentro do shadow DOM. Uma maneira de garantir que o conteúdo shadow DOM e o light DOM sejam exibidos no HTML renderizado é usar um 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>
            

Após a renderização, o Googlebot indexará este conteúdo:

<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>
    

Corrigir imagens e conteúdo de carregamento lento

As imagens podem demandar muita largura de banda e desempenho. Uma boa estratégia é usar carregamento lento para carregar imagens somente quando o usuário estiver prestes a vê-las. Para implementar o carregamento lento de forma otimizada para a pesquisa, siga nossas diretrizes.