Главная Статьи Оптимизация

SEO JavaScript-сайтов и SPA

Сайты на React, Vue, Angular и других JS-фреймворках выглядят современно и работают как приложение. Но у них есть коварная SEO-ловушка: контент рисуется JavaScript уже в браузере, а в исходном HTML — пусто. Если поисковик не выполнит этот JS, он увидит чистую страницу без текста и ничего не проиндексирует. Разберём, как сделать JS-сайт видимым для поиска.

Почему JS-сайты — проблема для SEO

Обычный сайт отдаёт готовый HTML с текстом — поисковик сразу его читает. SPA (single page application) отдаёт почти пустой HTML и пакет JavaScript, который уже в браузере подгружает данные и рисует контент. Робот должен сначала выполнить JS, чтобы увидеть текст. Яндекс и Google это умеют, но не всегда, не сразу и не идеально — рендеринг JS откладывается и тратит ресурсы, а часть контента может не попасть в индекс.

👤 Что видит пользователь
Заголовок товара
Цена, описание, кнопка купить — всё на месте.
🤖 Что видит робот в HTML
<body> <div id="root"></div> <script src="bundle.js"></script> </body>

Без выполнения JS робот видит пустой <div id="root"> — ни текста, ни ссылок.

Две волны индексации: почему JS ждёт

Даже когда робот умеет выполнять JavaScript (а Googlebot умеет), он делает это не сразу. Индексация JS-сайта идёт в две волны: сначала робот забирает и индексирует то, что уже есть в HTML, а рендеринг скриптов откладывает в отдельную очередь — она может разгребаться от нескольких часов до нескольких дней. Всё, что рисует JS, попадёт в индекс только во вторую волну, и то если рендеринг прошёл успешно.

Волна 1 — сразу Обход HTML Индекс: статический HTML ✓ сразу контент за JS откладывается → Волна 2 — с задержкой ⏳ Очередьрендеринга ⚙ Рендеринг JSheadless-браузер Индекс: JS-контент часы–дни
Что есть в HTML — индексируется сразу. Что рисует JavaScript — ждёт второй волны, и задержка может растянуться на дни.

Вывод из этой картины простой: чем больше важного контента в исходном HTML, тем быстрее и надёжнее он попадёт в поиск. Полагаться на то, что «робот дорендерит», — значит ставить индексацию в зависимость от очереди, на которую вы не влияете.

Способы рендеринга: что выбрать

CSR
Client-Side Rendering — рискованно для SEOКонтент рисуется только в браузере. Робот видит пустой HTML. Худший вариант для продвижения.
SSR
Server-Side Rendering — лучший для SEOСервер отдаёт уже готовый HTML с контентом, а JS «оживляет» интерактив. Робот сразу видит текст. Next.js, Nuxt и подобные.
SSG
Static Site Generation — отлично для SEOСтраницы генерируются заранее в статический HTML. Быстро и полностью индексируемо. Подходит для контента, который меняется нечасто.
Prerender
Пререндер / динамический рендеринг — компромиссРоботу отдаётся заранее отрендеренная версия страницы, людям — обычный SPA. Костыль, но спасает существующий CSR-проект.

Главный вывод: для SEO нужно, чтобы контент был в HTML до выполнения JS. Достигается это через SSR или SSG. Если переписать архитектуру нельзя — выручает пререндер.

Как проверить, видит ли поиск ваш контент

🛠
Базовую проверку (title, описание, заголовки, что отдаёт сервер) сделает анализ сайта и проверка ответа сервера. Как читать панель — Google Search Console.

Частые ошибки JS-сайтов

Про скорость и отзывчивость — статья Core Web Vitals (LCP, INP, CLS), про индексацию — краулинговый бюджет.

Чек-лист SEO для JS-сайта

Яндекс и JavaScript: отдельная осторожность

Важный нюанс для Рунета: Яндекс рендерит JavaScript заметно скромнее Google. Если ваш трафик в основном из Яндекса, надеяться на то, что робот «выполнит скрипты и всё увидит», тем более не стоит. Для Яндекса SSR или SSG — это почти обязательное условие нормальной индексации JS-сайта, а не один из вариантов. Проще говоря: то, что кое-как переваривает Googlebot, Яндекс может просто не увидеть. Делайте контент в HTML — и спор о возможностях рендеринга снимается для обоих.

Гидратация: контент в HTML, интерактив на JS

SSR и SSG не означают отказ от React или Vue. Работает это через гидратацию: сервер отдаёт готовый HTML с текстом (его сразу видят и человек, и робот), а затем тот же JS-фреймворк «оживляет» страницу в браузере — навешивает обработчики, делает её интерактивной. Лучшее из двух миров: индексируемость статики и удобство приложения. Подвох — ошибки гидратации: если разметка с сервера и то, что строит JS, расходятся, в консоли сыплются предупреждения, а часть контента может «мигать» или подменяться. Следите, чтобы серверная и клиентская версии совпадали.

Что робот точно не увидит

Даже на отрендеренной странице есть зоны, в которые робот не попадает. Их стоит знать, чтобы не прятать туда важное:

Маршрутизация: чистые URL вместо хэшей

В SPA есть два способа делать «страницы». Старый — через хэш в адресе (site.ru/#/catalog): всё после # поиск обычно игнорирует, поэтому такие маршруты плохо индексируются (а древняя схема #! для AJAX давно не поддерживается). Правильный — History API с обычными чистыми URL (site.ru/catalog): каждый маршрут — отдельный адрес, который можно отдать роботу с готовым HTML. Если делаете SPA, используйте History API и настройте сервер так, чтобы каждый такой URL открывался напрямую.

Как мигрировать с CSR на SSR без потери позиций

  1. Начните с самых важных по трафику шаблонов (категории, карточки, статьи) — переведите на SSR/SSG их в первую очередь.
  2. Сохраните прежние URL один-в-один: меняется рендеринг, а не адреса страниц.
  3. Проверьте, что мета-теги, заголовки и микроразметка теперь в исходном HTML.
  4. Выкатывайте по частям и следите за индексацией и позициями в Вебмастере и Search Console пару недель.

Коротко

SPA на React/Vue рисуют контент в браузере, а в исходном HTML пусто — и поисковик может не увидеть текст. Чтобы JS-сайт индексировался, контент должен быть в HTML до выполнения JS: это даёт SSR (сервер отдаёт готовый HTML) или SSG (статическая генерация). Если переписать нельзя — спасает пререндер для роботов. Проверяйте, виден ли контент без JS и в Search Console, делайте навигацию обычными ссылками, задавайте мета на сервере и следите за весом бандла. Тогда современный JS-сайт будет и красивым, и видимым для поиска.

Частые вопросы

Почему JavaScript-сайты плохо индексируются?
Потому что SPA отдаёт почти пустой HTML и пакет JavaScript, который рисует контент уже в браузере. Робот должен сначала выполнить JS, чтобы увидеть текст. Яндекс и Google это умеют, но не всегда, не сразу и не идеально — рендеринг откладывается, тратит ресурсы, и часть контента может не попасть в индекс.
Что лучше для SEO: SSR, CSR или SSG?
Для SEO лучше SSR (сервер отдаёт готовый HTML с контентом) или SSG (страницы заранее сгенерированы в статический HTML) — робот сразу видит текст. CSR (рендеринг только в браузере) — худший вариант, робот видит пустой HTML. Если переписать архитектуру нельзя, выручает пререндер для роботов.
Как проверить, видит ли поиск контент моего SPA?
Откройте исходный код страницы (Ctrl+U) или отключите JavaScript в браузере — виден ли основной текст и ссылки. Если пусто — проблема. Также используйте проверку URL в Google Search Console: она показывает отрендеренный HTML, как его видит Googlebot, и можно сравнить с исходным кодом.
Какие ошибки чаще всего у JS-сайтов в SEO?
Навигация на onClick вместо обычных ссылок-тегов a href (робот не «кликает»), контент, появляющийся только после клика или скролла (робот его не видит), мета-теги, проставляемые скриптом вместо сервера (ненадёжно), и слишком тяжёлый JS-бандл, который медленно грузится и ухудшает Core Web Vitals, особенно INP.
Нужен ли SSR, если у меня уже готовый SPA?
Если контент не виден в исходном HTML и страдает индексация — да, SSR или SSG решают проблему кардинально. Но если переписывать проект дорого, можно настроить динамический рендеринг (пререндер): роботу отдаётся заранее отрендеренная версия, людям — обычный SPA. Это компромисс, спасающий существующий CSR-проект.
Рендерит ли Яндекс JavaScript так же, как Google?
Нет, заметно скромнее. Если значимая часть трафика из Яндекса, на выполнение скриптов роботом полагаться нельзя — для Яндекса SSR или SSG это практически обязательное условие нормальной индексации JS-сайта. То, что кое-как переваривает Googlebot, Яндекс может просто не увидеть. Надёжный путь один: отдавать контент в исходном HTML.
Что такое гидратация и зачем она нужна?
Это механизм, при котором сервер отдаёт готовый HTML с контентом (его сразу видят человек и робот), а затем тот же JS-фреймворк оживляет страницу в браузере — навешивает обработчики и делает её интерактивной. Так совмещаются индексируемость статики и удобство приложения. Главное — чтобы серверная и клиентская разметка совпадали, иначе возникают ошибки гидратации.
Можно ли использовать хэш в URL у SPA (site.ru/#/page)?
Нежелательно. Всё, что после символа #, поиск обычно игнорирует, поэтому хэш-маршруты плохо индексируются, а старая схема #! для AJAX давно не поддерживается. Используйте History API с обычными чистыми URL (site.ru/page) и настройте сервер так, чтобы каждый такой адрес открывался напрямую с готовым HTML.