JavaScript a SEO – podstawy

JavaScript jest ważnym elementem platformy internetowej, ponieważ zapewnia wiele funkcji, które zamieniają obszary internetu w zaawansowane platformy aplikacji. Dbając o wykrywalność aplikacji internetowych opartych na JavaScripcie w wyszukiwarce Google, zwiększasz szansę na znalezienie nowych użytkowników i ponowne zaangażowanie dotychczasowych, gdy szukają oni treści, których dostarczyć mogą Twoje aplikacje. Wyszukiwarka Google obsługuje JavaScript przy użyciu zawsze aktualnej wersji Chromium, ale kilka rzeczy możesz zoptymalizować.

Dzięki temu przewodnikowi dowiesz się, jak wyszukiwarka Google przetwarza JavaScript, i poznasz sprawdzone metody ulepszania aplikacji internetowych utworzonych przy użyciu tego języka pod kątem ich wyszukiwania w Google.

Jak Google przetwarza JavaScript

Przetwarzanie aplikacji internetowych opartych na JavaScripcie przez Google można podzielić na 3 główne fazy:

  1. Skanowanie
  2. renderowanie,
  3. Indeksowanie

Googlebot pobiera URL z kolejki indeksowania, skanuje go, a potem przekazuje do etapu przetwarzania. Na tym etapie wyodrębniane są linki, które ponownie trafiają do kolejki indeksowania, a strona jest dodawana do kolejki renderowania. Stamtąd strona trafia do mechanizmu renderowania, który przekazuje wyrenderowany kod HTML do przetwarzania. Na etapie przetwarzania treści są indeksowane i wyodrębniane są linki, które trafiają do kolejki indeksowania.

Googlebot ustala kolejkę stron do skanowania i renderowania. Trudno jest natychmiastowo ustalić, kiedy strona czeka na skanowanie, a kiedy na renderowanie.

Gdy Googlebot pobiera URL z kolejki indeksowania, wysyłając żądanie HTTP, najpierw sprawdza, czy zezwalasz na indeksowanie. W tym celu czyta plik robots.txt. Jeśli URL jest w nim oznaczony jako niedozwolony, Googlebot nie wysyła do niego żądania HTTP i w rezultacie go pomija.

Następnie Googlebot analizuje odpowiedzi z innych adresów URL w atrybucie href linków HTML i dodaje te adresy do kolejki indeksowania. Aby zapobiec wykrywaniu linków, użyj mechanizmu nofollow.

Indeksowanie adresu URL i analizowanie odpowiedzi HTML sprawdza się w przypadku klasycznych witryn lub stron renderowanych po stronie serwera, gdy kod HTML w odpowiedzi HTTP zawiera wszystkie treści. Niektóre witryny korzystające z JavaScriptu mogą używać modelu powłoki aplikacji. W takim przypadku początkowy kod HTML nie zawiera rzeczywistych treści generowanych przez JavaScript, więc w celu ich podejrzenia Google musi wykonać kod JavaScript.

Googlebot umieszcza w kolejce wszystkie strony do renderowania, chyba że tag meta lub nagłówek w pliku robots wskazuje, żeby nie indeksować strony. Strona może znajdować się w kolejce przez kilka sekund albo dłużej. Gdy zezwolą na to zasoby Google, Chromium bez interfejsu graficznego renderuje stronę i wykonuje kod JavaScript. Googlebot ponownie analizuje wyrenderowany kod HTML pod kątem linków i dodaje znalezione adresy URL do kolejki indeksowania. Google używa również wyrenderowanego kodu HTML do zindeksowania strony.

Pamiętaj, że renderowanie po stronie serwera lub wstępne renderowanie nadal jest bardzo użyteczne, bo sprawia, że witryna działa szybciej dla użytkowników i robotów, a poza tym nie wszystkie boty potrafią wykonywać kod JavaScript.

Opisywanie strony przy użyciu unikalnych tytułów i fragmentów

Unikalne, opisowe elementy <title> i przydatne metaopisy pomagają użytkownikom szybko zidentyfikować najlepszy wynik. Informacje na temat dobrych elementów <title>metaopisów znajdziesz w naszym poradniku.

Do określenia lub zmiany metaopisu bądź elementu <title> możesz użyć JavaScriptu.

W zależności od zapytania użytkownika wyszukiwarka Google może pokazać inny link z tytułem. Dzieje się tak, gdy Twój tytuł lub opis w niewielkim stopniu odzwierciedla zawartość strony albo gdy znajdziemy na niej alternatywne treści, które lepiej pasują do wyszukiwanego hasła. Dowiedz się więcej o tym, dlaczego tytuł w wynikach wyszukiwania może być inny niż w elemencie <title> strony.

Pisanie zgodnego kodu

Przeglądarki oferują wiele interfejsów API, a JavaScript jest językiem, który szybko się rozwija. Z kolei Google obsługuje ograniczoną liczbę interfejsów API i funkcji JavaScriptu. Aby sprawdzić, czy Twój kod jest zgodny z Google, postępuj według naszych wskazówek dotyczących rozwiązywania problemów z obsługą JavaScriptu.

Jeśli wykryjesz brakujący interfejs API, zalecamy użycie zróżnicowanego wyświetlania i kodu polyfill. Niektórych funkcji przeglądarek nie da się obsłużyć kodem polyfill. Informacje o potencjalnych ograniczeniach znajdziesz w jego dokumentacji.

Używanie znaczących kodów stanu HTTP

Googlebot używa kodów stanu HTTP, żeby wykrywać, czy podczas indeksowania strony coś poszło nie tak.

Jeśli chcesz przekazać Googlebotowi, żeby nie skanował ani nie indeksował strony, używaj znaczących kodów stanu – na przykład kodu 404 w przypadku strony, której nie można znaleźć, lub kodu 401 w przypadku stron, na które trzeba się zalogować. Tych kodów możesz też używać, aby informować Googlebota o przeniesieniu strony pod nowy URL. Dzięki temu będzie można odpowiednio zaktualizować indeks.

Oto lista kodów stanu HTTP wraz z informacjami o ich wpływie na wyszukiwarkę Google.

Unikaj błędów soft 404 w aplikacjach na jednej stronie

W przypadku aplikacji na jednej stronie renderowanych po stronie klienta kierowanie ruchu jest często implementowane jako kierowanie ruchu po stronie klienta. W tym przypadku używanie znaczących kodów stanu HTTP może się okazać niemożliwe lub niepraktyczne. Aby uniknąć błędów soft 404 podczas korzystania z kierowania ruchu i renderowania po stronie klienta, użyj jednej z tych strategii:

  • Użyj przekierowania JavaScript na adres URL, na który serwer wysyła kod stanu HTTP 404 (na przykład /not-found).
  • Dodaj kod <meta name="robots" content="noindex"> do stron błędów za pomocą JavaScriptu.

Oto przykładowy kod przekierowania:

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

Oto przykładowy kod z tagiem 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 robots meta tag present in the HTML.
    const metaRobots = document.createElement('meta');
    metaRobots.name = 'robots';
    metaRobots.content = 'noindex';
    document.head.appendChild(metaRobots);
  }
})

Używanie interfejsu History API zamiast adresów URL zawierających fragment z krzyżykiem

Google może zindeksować Twój link tylko wtedy, gdy jest to element HTML <a> z atrybutem href.

W przypadku aplikacji jednostronicowych z kierowaniem ruchu po stronie klienta użyj interfejsu History API, aby zaimplementować kierowanie ruchu między różnymi widokami aplikacji internetowej. Aby umożliwić Googlebotowi analizowanie i wyodrębnianie adresów URL, unikaj używania fragmentów do wczytywania innej treści strony. Poniżej znajdziesz przykład niezalecanego działania, ponieważ Googlebot nie jest w stanie w prawidłowy sposób rozpoznać adresów URL:

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

Adresy URL będą dostępne dla Googlebota, jeśli zamiast tego zaimplementujesz interfejs 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>

Choć nie zalecamy do używania w tym celu JavaScriptu, wstrzyknięcie tagu link rel="canonical" za jego pomocą jest możliwe. Wyszukiwarka Google pobierze wstrzyknięty kanoniczny URL podczas renderowania strony. Oto przykład wstawienia tagu link rel="canonical" za pomocą kodu JavaScript:

fetch('/api/cats/' + id)
  .then(function (response) { return response.json(); })
  .then(function (cat) {
    // creates a canonical link tag and dynamically builds the URL
    // e.g. https://example.com/cats/simba
    const linkTag = document.createElement('link');
    linkTag.setAttribute('rel', 'canonical');
    linkTag.href = 'https://example.com/cats/' + cat.urlFriendlyName;
    document.head.appendChild(linkTag);
  });

Rozważne używanie tagów meta robots

Aby uniemożliwić robotowi Google indeksowanie strony lub otwieranie linków, możesz użyć tagu meta robots. Na przykład dodanie tego tagu meta w górnej części strony blokuje Google możliwość indeksowania tej strony:

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

Możesz użyć JavaScriptu, aby dodać tag meta robots do strony lub zmień jej zawartość. Poniższy przykładowy kod pokazuje, jak zmienić tag meta robots za pomocą JavaScriptu, aby zapobiec indeksowaniu bieżącej strony, jeśli wywołanie interfejsu API nie zwróci treści.

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

Gdy Google napotyka dyrektywę noindex w tagu meta robots przed uruchomieniem JavaScriptu, nie renderuje ani nie indeksuje strony.

Używanie długiego buforowania

Googlebot intensywnie korzysta z pamięci podręcznej, aby zmniejszać liczbę żądań sieciowych i wykorzystanie zasobów. WRS może ignorować nagłówki zapisu w pamięci podręcznej. Może to prowadzić do korzystania przez WRS z nieaktualnych zasobów JavaScriptu lub CSS-u. Uniknąć tego problemu pozwala odcisk cyfrowy treści umieszczany we fragmencie nazwy pliku odnoszącym się do zawartości, np. main.2bb85551.js. Odcisk cyfrowy zależy od zawartości pliku, więc jej aktualizacje powodują każdorazowe utworzenie innej nazwy pliku. Więcej informacji znajdziesz w przewodniku web.dev po strategiach długiego buforowania.

Używanie uporządkowanych danych

Jeśli na swoich stronach stosujesz uporządkowane dane, możesz używać JavaScriptu do generowania wymaganego kodu JSON-LD i wstrzykiwania go do strony. Aby uniknąć problemów, przetestuj swoją implementację.

Trzymanie się sprawdzonych metod korzystania z komponentów internetowych

Google obsługuje komponenty internetowe. Renderując stronę, Google spłaszcza treści Shadow DOM i Light DOM. Oznacza to, że Google może wyświetlać tylko treści, które są widoczne w renderowanym kodzie HTML. Aby sprawdzić, czy Google nadal widzi Twoje treści po ich wyrenderowaniu, przeprowadź test wyników z elementami rozszerzonymi lub użyj narzędzia do sprawdzania adresów URL i przyjrzyj się wyrenderowanemu kodowi HTML.

Jeśli treść nie jest widoczna w wyrenderowanym kodzie HTML, robot Google nie będzie mógł jej zindeksować.

W poniższym przykładzie tworzony jest komponent internetowy, który wyświetla treść Light DOM w modelu Shadow DOM. Jednym ze sposobów zagwarantowania, że w wyświetlonym kodzie HTML będzie wyświetlana zarówno treść Light DOM, jak i Shadow DOM, jest użycie elementu Przedział.

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

Po wyrenderowaniu Google może zindeksować te treści:

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

Rozwiązywanie problemów z obrazami i leniwym ładowaniem treści

Obsługa obrazów może znacznie obciążać przepustowość i wymagać sporej mocy obliczeniowej. Dlatego dobrym podejściem jest stosowanie leniwego ładowania, aby wczytywane były tylko te obrazy, które użytkownik za chwilę zobaczy. Aby sprawdzić, czy używasz leniwego ładowania tak, aby nie utrudniało działania wyszukiwarek, postępuj według naszych wskazówek.

Projektowanie z myślą o dostępności

Twórz strony z myślą o użytkownikach, a nie tylko wyszukiwarkach. Projektując witrynę, warto pamiętać o potrzebach użytkowników, również tych, którzy nie używają przeglądarek z JavaScriptem (są to np. osoby korzystające z czytników ekranu lub mniej zaawansowanych urządzeń mobilnych). Ułatwienia dostępu witryny można łatwo sprawdzić – wystarczy wyłączyć obsługę JavaScriptu w przeglądarce lub użyć przeglądarki tekstowej, takiej jak Lynx. Przeglądanie witryny w trybie tekstowym ułatwia też identyfikację innych treści trudno dostępnych dla Google, np. tekstu umieszczonego w grafice.