Frog Proger 22 ноября 2024

🔍📊 10 методов SEO-оптимизации JavaScript, которые должен знать каждый фронтендер

Веб-приложения часто используют JavaScript для динамического создания контента и удобного взаимодействия с пользователем. Но поисковые роботы не всегда могут правильно прочитать и проиндексировать такой контент – в итоге сайт теряет посетителей. На помощь придут 10 способов SEO-оптимизации для JavaScript.
🔍📊 10 методов SEO-оптимизации JavaScript, которые должен знать каждый фронтендер
Этот материал взят из нашей еженедельной email-рассылки, посвященной фронтенду. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

Серверный и статический рендеринг

Многие сайты активно используют JavaScript для загрузки и отображения контента. Однако поисковые системы (включая Google) не всегда могут корректно выполнить этот JavaScript-код. В результате страницы индексируются в неполном и/или искаженном виде, что очень негативно сказывается на SEO. Для решения этой проблемы необходимо использовать рендеринг на стороне сервера (SSR) или генерацию статических страниц.

SSR

При серверном рендеринге содержимое страницы формируется на сервере, а не в браузере пользователя. Клиент сразу получает готовую HTML-страницу, которая содержит все необходимое, включая контент и динамические элементы.

Плюсы:

  • Страница загружается быстрее, так как браузер не ждет выполнения JavaScript.
  • Поисковые системы видят полностью готовый контент.
  • Подходит для страниц с динамическим контентом.

Генерация статических страниц

При этом подходе содержимое страницы формируется на этапе сборки, а затем сохраняется как статические HTML-файлы. Эти файлы загружаются при обращении к сайту.

Плюсы:

  • Очень быстро работает, так как сервер просто отдает готовую HTML-страницу.
  • Хорошо подходит для статичного контента, который редко меняется.

Пример: SSR с использованием Next.js

В этом примере сервер выполняет функцию getServerSideProps, запрашивает данные с API (https://api.example.com/data), добавляет их в HTML, и отправляет клиенту уже полностью отрисованную страницу.

        // pages/index.js
import React from 'react';
 
const Home = ({ data }) => (
  <div>
    <h1>{data.title}</h1>
    <p>{data.description}</p>
  </div>
);
 
export async function getServerSideProps() {
  // Fetch data at runtime
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
 
  return { props: { data } };
}
 
export default Home;
    

Тег rel="canonical"

JavaScript-фреймворки могут создавать несколько версий одной и той же страницы. Это особенно часто происходит в случаях, когда URL-адреса различаются из-за параметров, фильтров или состояния навигации пользователя. В результате, поисковые системы могут воспринимать такие страницы как дубликаты, что приводит к «размыванию» сигналов ранжирования (несколько версий одной страницы будут конкурировать друг с другом в результатах поиска).

Для решения этой проблемы используется тег rel="canonical", который указывает предпочтительную (каноническую) версию страницы. Добавление этого тега позволяет:

  • Объединить все дублирующие URL-адреса в одну авторитетную страницу.
  • Избежать разделения сигналов ранжирования между дублированными страницами.
  • Сохранить эффективность обратных ссылок, которые могут терять ценность из-за ложных сигналов о дубликатах.
        <head>
  <link rel="canonical" href="https://www.example.com/original-page" />
</head>
    

Корректная маршрутизация

Маршрутизация на стороне клиента, например, с React Router, удобна для создания динамических SPA-приложений. Однако неправильная реализация может привести к проблемам с индексацией. Чтобы этого избежать:

  • Обеспечьте доступность контента через внутренние ссылки. Используйте элементы <Link> вместо <a> для внутренних переходов. Это помогает поисковым системам правильно интерпретировать и индексировать страницы.
  • Обновляйте URL без перезагрузки всей страницы. Используйте метод history.pushState() для изменения URL, чтобы приложение оставалось динамичным, а пользовательский опыт был плавным.
        import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
 
function App() {
  return (
    <Router>
      <nav>
        <Link to="/about">About Us</Link>
        <Link to="/contact">Contact</Link>
      </nav>
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </Router>
  );
}
    

Правильная реализация отложенной загрузки

Отложенная (ленивая) загрузка позволяет улучшить скорость загрузки страницы и общую производительность сайта: второстепенный контент загружается не сразу, а только когда он действительно необходим пользователю. Однако поисковики могут не проиндексировать важный контент, если он загружается слишком поздно, либо поисковые роботы не могут запустить JavaScript, необходимый для его загрузки. Для правильной ленивой загрузки нужно:

  • В первую очередь загружать контент, попадающий в поле зрения при открытии страницы (над уровнем прокрутки).
  • Обеспечить запасные варианты для элементов с отложенной загрузкой.
  • Использовать Intersection Observer API для эффективной загрузки изображений.
        // Lazy loading images
const images = document.querySelectorAll('img[data-src]');
 
const imgObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});
 
images.forEach(img => {
  imgObserver.observe(img);
});
    

Предварительный рендеринг

Предварительный рендеринг – эффективное решение для страниц с большим количеством JavaScript-кода, которые некорректно индексируются поисковиками.

Суть проблемы:

  • Контент может быть скрыт за сложными JavaScript-взаимодействиями или экранами входа.
  • Поисковые роботы испытывают проблемы с обработкой такого динамического контента.

Решение:

Сервисы пре-рендеринга (например, Prerender.io или Rendertron) создают статические HTML-версии страниц специально для поисковых роботов. При этом:

  • Обычные пользователи продолжают видеть динамическую версию сайта.
  • Поисковые роботы получают готовую HTML-версию, которую легко индексировать.
        const express = require('express');
const prerender = require('prerender-node');
 
const app = express();
app.use(prerender.set('prerenderToken', 'YOUR_TOKEN_HERE'));
 
app.get('/', (req, res) => {
  res.send('Hello World!');
});
 
app.listen(3000);
    

Динамические мета-теги

Мета-теги помогают поисковым системам понять содержание страницы и влияют на коэффициент кликабельности (CTR), когда страница отображается в результатах поиска. Для сайтов на JavaScript эти теги должны генерироваться динамически, чтобы отражать актуальное содержание страницы. Это особенно важно для приложений, которые используют ИИ для генерации лидов или для автоматизации других процессов. Динамически обновлять мета-теги в зависимости от контента можно с помощью инструментов типа react-helmet: он обеспечивает корректную и оптимизированную метаинформацию, которую видят поисковые системы и соцсети. Такой подход улучшает ранжирование в поиске и повышает привлекательность страниц при их публикации в соцсетях:

        import { Helmet } from 'react-helmet';
 
function BlogPost({ title, description }) {
  return (
    <div>
      <Helmet>
        <title>{title}</title>
        <meta name="description" content={description} />
      </Helmet>
      <h1>{title}</h1>
      <p>{description}</p>
    </div>
  );
}
    

Настройки robots.txt

Важно правильно настроить файл robots.txt: ограничить доступ к конфиденциальным областям сайта, сохраняя при этом доступ к важным ресурсам, необходимым для индексирования. Allow: /js/ разрешает доступ к каталогу с JavaScript-файлами, чтобы поисковые системы могли правильно рендерить страницы:

        User-agent: *
Disallow: /private/
Allow: /js/
    

Навигационная цепочка с JSON-LD

«Хлебные крошки» улучшают навигацию как для пользователей, так и для поисковых систем: Google отображает их в результатах поиска, что помогает пользователям лучше понять структуру сайта и повышает кликабельность (CTR). Правильное структурирование навигационной цепочки, например с помощью JSON-LD, позволяет поисковым системам корректно интерпретировать хлебные крошки и повышает их видимость в поисковых системах:

        <script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://www.example.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://www.example.com/blog"
    }
  ]
}
</script>
    

Управление бюджетом сканирования

Бюджет сканирования – это количество страниц, которые поисковая система обходит на сайте за определенное время. Сложные JavaScript-скрипты и ненужные вызовы API могут израсходовать этот бюджет, что приведет к тому, что не все страницы будут просканированы и проиндексированы. Чтобы повысить эффективность сканирования, необходимо:

  • Минимизировать сложность JavaScript-кода.
  • Избегать ненужных внешних вызовов API во время загрузки страниц.
  • Сокращать вес JavaScript-бандлов для ускорения загрузки страниц, чтобы поисковые системы могли обходить больше контента.

В этом примере ненужные вызовы API исключены с использованием sessionStorage, что позволяет сохранять данные между перезагрузками страницы:

        function loadData() {
  if (!sessionStorage.getItem('dataLoaded')) {
	fetch('https://api.example.com/data')
  	.then(response => response.json())
  	.then(data => {
    	// Process data
    	console.log(data);
    	sessionStorage.setItem('dataLoaded', true);
  	})
  	.catch(error => console.error('Error fetching data:', error));
  }
}
 
document.addEventListener('DOMContentLoaded', loadData);
    

Поддержание чистоты URL

Одностраничные SPA-приложения могут порождать URL с параметрами запросов или фрагментами #, которые портят показатели SEO. Метод window.history.replaceState() обновляет URL в адресной строке без перезагрузки страницы и поддерживает соответствие URL отображаемому контенту:

        // Clean up URL after loading dynamic content
window.history.replaceState(null, 'New Page Title', '/new-url-path');
    

В заключение

JavaScript делает фронтенд динамичным и интерактивным, но его использование должно быть тщательно продумано с точки зрения SEO. Следуя этим рекомендациям, вы сможете повысить позиции сайта в поисковых системах без ущерба для пользовательского опыта.

***

Хочешь освоить Frontend с нуля? В Proglib Academy запускается двухмесячный курс Frontend Basic от практиков из топовых компаний: от основ HTML до полноценных React-приложений, с персональной поддержкой и пожизненным доступом к материалам.

Источники

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ