SEO для JavaScript-сайтов: SSR, SSG и CSR на React и Next.js
Продвинутое3 минРедакция Innovialabs
Коротко
Для SEO надёжнее всего отдавать готовый HTML с контентом через SSR или SSG. CSR, где страница собирается в браузере, заставляет поисковик рендерить JS, а это медленнее и не всегда срабатывает.
Коротко: какой рендеринг выбрать
Если страница должна ранжироваться, её основной контент, ссылки и метатеги должны быть в HTML-ответе сервера. Это дают SSR (рендеринг на сервере) и SSG (генерация статических страниц при сборке). CSR, когда сервер отдаёт пустую оболочку, а контент собирает JavaScript в браузере, подходит для личных кабинетов и админок, но рискован для публичных страниц.
Как поисковики обрабатывают JavaScript
Googlebot сначала получает HTML, затем ставит страницу в очередь на рендеринг и выполняет JavaScript в современном Chromium. Между сканированием и рендерингом может пройти время, а часть ресурсов может не загрузиться из-за таймаутов или блокировок в robots.txt.
Яндекс тоже умеет рендерить JavaScript, но полагаться на это для ключевого контента рискованнее. Безопасная стратегия для обоих поисковиков одна: важное — сразу в HTML.
Что боты обычно не делают:
- не кликают по кнопкам и не прокручивают страницу ради подгрузки контента;
- не переходят по ссылкам, сделанным через
onClickбезhref; - не видят контент, который появляется только после действия пользователя.
Сравнение стратегий
| Стратегия | Где формируется HTML | SEO | Когда подходит |
|---|---|---|---|
| SSG | При сборке | Отлично | Блог, лендинги, документация |
| ISR / ревалидация | При сборке и периодически | Отлично | Каталоги, которые меняются не каждую секунду |
| SSR | На сервере при запросе | Отлично | Персональные или часто меняющиеся данные |
| CSR | В браузере | Рискованно | Закрытые разделы, дашборды |
В Next.js страницы по умолчанию рендерятся на сервере, а клиентские компоненты гидрируются в браузере. Детали API меняются между версиями, поэтому сверяйтесь с официальной документацией вашей версии.
Проблемы гидрации
Гидрация — это когда React в браузере «оживляет» HTML, пришедший с сервера. Если разметка на сервере и в браузере отличается, возникает ошибка гидрации: React может перерисовать участок, а пользователь увидит мигание.
Типичные причины:
- использование
Date.now(),Math.random()илиwindowпри рендере; - разный контент для сервера и клиента в зависимости от локали или часового пояса;
- некорректная вложенность HTML, например
<div>внутри<p>.
"use client";
import { useEffect, useState } from "react";
export function LocalTime() {
const [time, setTime] = useState<string | null>(null);
useEffect(() => setTime(new Date().toLocaleTimeString()), []);
return <span>{time ?? ""}</span>;
}
Значения, зависящие от браузера, вычисляйте после монтирования, а не во время рендера.
Как проверить, что видит бот
- Исходный код страницы (не DevTools): есть ли там текст, ссылки, title и description.
- curl с сервера — быстрая проверка HTML без JavaScript.
- Проверка URL в Google Search Console: вкладка с отрендеренным HTML и скриншотом.
- Яндекс Вебмастер: проверка ответа сервера и статуса страниц в индексе.
- Отключите JavaScript в браузере и посмотрите, что осталось.
curl -s https://example.uz/catalog | grep -i "<title>"
Частые ошибки
- Метатеги и canonical добавляются только на клиенте.
- Навигация без настоящих
<a href>. - Бесконечная прокрутка без страниц с отдельными URL.
- JS- и CSS-файлы закрыты в robots.txt.
- Сервер отдаёт код 200 для несуществующих страниц, а «404» рисует JavaScript.