JavaScript-SEO: как продвигать сайты на React, Vue и SPA

Сайты на React, Vue и Angular выглядят современно и быстро работают для пользователя, но для поискового робота они нередко превращаются в пустую страницу без текста и ссылок. Если контент собирается в браузере с помощью JavaScript, его можно вообще не увидеть в индексе — а значит, не получить ни позиций, ни трафика. В этой статье разбираем, как устроена индексация JS-сайтов и как настроить рендеринг так, чтобы SEO-продвижение приносило результат даже на самом «тяжёлом» фронтенде.
Коротко
- Поисковый робот сначала читает исходный HTML, и только потом (не всегда) исполняет JavaScript — если в первом HTML нет контента, индексация замедляется или срывается.
- Чистый клиентский рендеринг (CSR) — самый рискованный вариант для SEO; безопаснее SSR или статическая генерация (SSG).
- Яндекс исполняет JavaScript хуже Google, поэтому для рунета серверный рендеринг почти обязателен.
- Большинство проблем — это не «магия фреймворка», а конкретные ошибки: ссылки через onclick, контент по клику, hash-роутинг, блокировка JS в robots.txt.
Почему сайты на JavaScript сложны для индексации
Классический сайт отдаёт серверу готовый HTML: робот скачивает страницу и сразу видит заголовки, текст, ссылки и микроразметку. Сайт на JS-фреймворке устроен иначе. Сервер отдаёт почти пустую оболочку — обычно это один div с id="root" или id="app" и подключённый бандл скриптов. Весь контент — тексты, карточки товаров, меню, ссылки — генерируется уже в браузере, когда JavaScript отработает. Для пользователя это незаметно: страница собирается за доли секунды. Для робота это означает, что в момент первого запроса смысловой нагрузки на странице нет.
Поисковая система обязана решить: исполнять этот JavaScript или нет. Исполнение скриптов — дорогая операция. Робот должен запустить полноценный браузерный движок, дождаться загрузки всех ресурсов, выполнить код, дождаться ответов от API. Это в десятки раз затратнее, чем просто скачать текстовый HTML. Поэтому поисковики не рендерят каждую страницу сразу — они откладывают рендеринг в отдельную очередь, и эта очередь может растягиваться от нескольких дней до нескольких недель.
Отсюда главный риск JS-SEO: если важный контент появляется только после исполнения скриптов, между сканированием страницы и попаданием контента в индекс возникает разрыв. Для нового сайта или часто обновляемого каталога это критично — товары, статьи и услуги попадают в поиск с большим опозданием либо не попадают вовсе, если на этапе рендеринга что-то пошло не так.
Что видит робот: исходный HTML против отрендеренного DOM
Ключевое различие, которое нужно усвоить владельцу JS-сайта, — это разница между двумя состояниями страницы. Исходный HTML — то, что сервер отдаёт в ответ на запрос, до исполнения скриптов. Именно его вы видите в браузере по команде «Просмотр исходного кода страницы» (Ctrl+U). Отрендеренный DOM — то, во что превращается страница после того, как JavaScript отработал; его видно в инструментах разработчика во вкладке Elements.
Проверьте свой сайт прямо сейчас: откройте товар или статью, нажмите Ctrl+U и поищите в исходном коде основной текст страницы или заголовок H1. Если по Ctrl+U контента нет, а в инструментах разработчика (F12, вкладка Elements) он есть — значит, ваш сайт рендерится на клиенте, и весь контент существует только в отрендеренном DOM. Поисковик увидит его лишь после исполнения JavaScript, которое, как мы выяснили, происходит не всегда и не сразу.
Это та самая точка, где теряется трафик. Робот при первом проходе индексирует исходный HTML. Если там пусто, страница в индексе будет либо без контента, либо с заглушкой «Loading…». Все ваши тексты, тщательно собранное семантическое ядро и проработанные метатеги окажутся бесполезны, пока робот не доберётся до второй волны — до рендеринга.
Если основной контент страницы не виден в исходном HTML по Ctrl+U — для поисковика этой страницы пока не существует. Всё остальное в JS-SEO вторично.
Двухволновая индексация Google и особенности Яндекса
Google официально описывает индексацию JS-сайтов как двухволновую (two-wave indexing). В первой волне робот скачивает и обрабатывает исходный HTML — то, что пришло с сервера. Он находит ссылки, ставит страницу в очередь, индексирует тот текст, что есть. Во второй волне страница попадает в очередь рендеринга (Web Rendering Service), где Googlebot запускает headless-браузер на движке Chromium, исполняет JavaScript, формирует финальный DOM и уже его передаёт в индекс. Между волнами проходит время — от часов до недель, в зависимости от приоритета сайта и нагрузки.
Для Google это означает: технически он умеет индексировать JS-контент, но с задержкой и при условии, что вы не мешаете ему рендерить. Если страница часто меняется (новости, цены, остатки), задержка второй волны бьёт по актуальности. Если на сайте миллионы страниц, очередь рендеринга съедает краулинговый бюджет, и часть контента просто не доходит до индекса.
С Яндексом ситуация жёстче. Робот Яндекса исполняет JavaScript значительно хуже Google: он умеет обрабатывать скрипты, но делает это менее полно и менее стабильно. На практике это означает, что полагаться на клиентский рендеринг в рунете нельзя — Яндекс с высокой вероятностью проиндексирует только исходный, почти пустой HTML. Поэтому для проектов, ориентированных на российскую аудиторию, серверный рендеринг или статическая генерация — это не опция, а обязательное условие. Если основной поисковик для вашего бизнеса Яндекс, чистый CSR закрывает вам дорогу в ТОП ещё до начала работы.
ВАЖНО ПРО ЯНДЕКС
Google «прощает» JavaScript, Яндекс — нет. Если ваша основная аудитория в рунете, исходите из того, что робот вообще не исполнит ваши скрипты, и отдавайте готовый HTML с сервера. Проверять индексацию обязательно в обеих системах отдельно — успех в Google ничего не говорит про Яндекс.
Виды рендеринга: CSR, SSR, SSG, динамический рендеринг и гидрация
Стратегия рендеринга — это то, где именно собирается HTML страницы: в браузере пользователя, на сервере при запросе или заранее на этапе сборки. От выбора напрямую зависит, увидит ли робот контент. Разберём основные подходы.
CSR (Client-Side Rendering, клиентский рендеринг) — классика чистого React или Vue. Сервер отдаёт пустую оболочку, весь HTML строится в браузере. Лучший вариант по интерактивности, худший по SEO. Подходит для закрытых разделов (личный кабинет, админка, дашборды), которым индексация не нужна.
SSR (Server-Side Rendering, серверный рендеринг) — сервер исполняет JavaScript и отдаёт роботу и пользователю готовый HTML с контентом. Робот сразу видит текст и ссылки в первой волне, рендеринг ему не нужен. Это золотой стандарт SEO для динамических сайтов. Реализуется через Next.js (React), Nuxt (Vue), Angular Universal. Минус — нагрузка на сервер и более сложная архитектура.
SSG (Static Site Generation, статическая генерация) — HTML всех страниц генерируется заранее, на этапе сборки проекта, и отдаётся как готовые статические файлы. Максимально быстро и максимально дружелюбно к поисковикам. Идеально для контента, который меняется не каждую секунду: блог, лендинги, документация, витрина услуг. Минус — при тысячах часто меняющихся страниц пересборка становится тяжёлой.
Динамический рендеринг и пререндеринг — компромисс: сайт определяет, кто пришёл. Пользователю отдаётся обычная CSR-версия, а поисковому роботу — заранее отрендеренный статический HTML (через сервис типа Prerender.io или собственный headless-браузер). Google относится к этому терпимо как к временному решению, но это «костыль»: вы поддерживаете две версии и рискуете рассинхроном. Для нового проекта лучше сразу заложить SSR или SSG.
Гидрация (hydration) — не отдельный вид рендеринга, а процесс «оживления». При SSR/SSG сервер отдаёт готовый HTML, а затем в браузере подгружается JavaScript и «привязывается» к этой разметке, делая её интерактивной. Для SEO важно: пока гидрация идёт, контент уже виден роботу из серверного HTML. Но если гидрация тяжёлая и долгая, страдают Core Web Vitals и пользовательский опыт.
Таблица: сравнение видов рендеринга по SEO
| Тип | Контент в исходном HTML | Дружелюбность к SEO | Для чего подходит |
|---|---|---|---|
| CSR (клиентский) | Нет, только пустая оболочка | Низкая (риск для Яндекса критичен) | Личные кабинеты, админки, закрытые разделы |
| SSR (серверный) | Да, готовый HTML | Высокая | Каталоги, маркетплейсы, динамика, рунет |
| SSG (статика) | Да, заранее собранный | Максимальная | Блоги, лендинги, услуги, документация |
| Динамический рендеринг | Для робота — да, для юзера — нет | Средняя (временное решение) | Легаси-проекты, миграция в переходный период |
| SSR + гидрация | Да, плюс интерактивность | Высокая при быстрой гидрации | Современные приложения с богатым UX |
Почему чистый CSR опасен для SEO
Соблазн оставить чистый CSR понятен: он проще в разработке, дешевле в хостинге, фронтенд-команда привыкла к нему. Но для проекта, который должен приводить органический трафик, это ловушка. Перечислим, что именно ломается.
Во-первых, задержка индексации. Контент попадает в индекс только после второй волны рендеринга, а это дни и недели для Google и почти никогда для Яндекса. Во-вторых, потеря части контента: если при рендеринге случилась ошибка JavaScript, упал запрос к API или истёк таймаут, робот зафиксирует пустую страницу — и проиндексирует пустоту. В-третьих, метатеги. При CSR title и description часто проставляются скриптом после загрузки, и в исходном HTML стоят дефолтные значения — робот видит одинаковые заглушки на всех страницах.
В-четвёртых, страдает скорость. CSR требует скачать и исполнить большой бандл до того, как пользователь увидит контент, что бьёт по Core Web Vitals и по скорости загрузки сайта — а это прямые факторы ранжирования и в Google, и в Яндексе. Если вы только выбираете технологию для будущего проекта, обсудите стек на этапе создания сайта: правильно выбранный фреймворк с поддержкой SSR избавит от половины проблем заранее.
Типичные ошибки JS-SEO
Даже на сайте с серверным рендерингом легко наделать ошибок, которые сводят на нет всю работу. Вот частые проблемы, которые мы находим на аудитах JS-проектов.
Подгрузка по клику и скроллу
Если текст, отзывы или характеристики появляются только после клика по вкладке или прокрутки (lazy load по событию), робот их не увидит. Важный контент должен быть в DOM сразу, без действий пользователя.
onclick вместо <a href>
Навигация через onclick или router.push без честного атрибута href не передаёт ссылочный вес и часто не сканируется. Все внутренние переходы — только обычными ссылками с href.
Hash-роутинг через #
URL вида site.ru/#/catalog/item — фрагмент после решётки роботом игнорируется. Используйте History API и нормальные ЧПУ-адреса без хеша.
Блокировка JS и CSS
Если в robots.txt закрыты папки со скриптами и стилями, робот не сможет отрендерить страницу и увидит её сломанной. JS и CSS должны быть открыты.
К этому добавим ещё несколько частых бед. Пустой первый HTML — когда даже при заявленном SSR на части страниц рендеринг не срабатывает и робот получает оболочку. Медленная гидрация — страница «дёргается», метрика INP проседает, поведенческие ухудшаются. Soft 404 — несуществующий товар отдаёт код 200 и пустую страницу вместо честного 404, и такие пустышки засоряют индекс. Каждая из этих ошибок по отдельности способна обрушить органику, а в сочетании они гарантированно держат сайт вне ТОПа. Подробнее про управление сканированием смотрите в материале про краулинговый бюджет и про настройку robots.txt.
Как проверить, индексируется ли JS-контент
Диагностика — первый шаг перед любыми переделками. Не нужно гадать: есть точные способы увидеть страницу глазами робота.
Просмотр исходного кода (Ctrl+U)
Откройте страницу, нажмите Ctrl+U и поищите основной текст и H1. Нет в исходнике — значит контент рендерится на клиенте и под угрозой. Это самая быстрая проверка за пять секунд.
Сравнение с отрендеренным DOM
Откройте инструменты разработчика (F12), вкладку Elements. Если в DOM контент есть, а в Ctrl+U его нет — это и есть разрыв между исходным HTML и отрендеренной страницей.
Инструмент проверки URL в Search Console
В Google Search Console используйте «Проверка URL» и посмотрите HTML, который получил робот, плюс скриншот отрендеренной страницы. Так видно, что реально попало в индекс.
Сохранённая копия и Яндекс Вебмастер
Посмотрите сохранённую копию страницы в выдаче и используйте инструменты Яндекс Вебмастера. Если в сохранённой копии текста нет — Яндекс контент не увидел.
Запрос без JavaScript
Отключите JavaScript в браузере и перезагрузите страницу. Что осталось видно — то примерно и видит «слабый» робот вроде Яндекса. Пустая страница — приговор для CSR.
Хороший приём — забить уникальную фразу из текста страницы в поиск с оператором точного совпадения. Если страница находится по этой фразе, контент проиндексирован. Если нет — робот его не увидел, даже если визуально на сайте всё на месте. Эту проверку стоит сделать частью регулярного контроля индексации сайта.
Метатеги, title и роутинг в SPA
В одностраничном приложении (SPA) при переходе между «страницами» URL меняется, а полной перезагрузки нет — обновляется только часть DOM. Проблема в том, что по умолчанию title, description и canonical при таком переходе не меняются: робот, дошедший до внутренней страницы, видит метатеги главной. Результат — дубли title и description по всему сайту и каша в сниппетах.
Решение — управление метатегами на смену роута. В React это библиотеки вроде react-helmet или встроенные средства Next.js (метаданные на уровне страницы), во Vue — соответствующие плагины Nuxt. Каждый маршрут должен выставлять свои уникальные title и description, свой canonical, корректные Open Graph и при необходимости hreflang. Но критично: при SSR/SSG эти метатеги должны попадать в исходный HTML, а не проставляться скриптом постфактум — иначе для «слабого» робота они снова окажутся невидимы.
Отдельно проследите за каноническими адресами и дублями. SPA легко плодит технические дубли: со слешем и без, с параметрами фильтров, с разным регистром. Каждая такая вариация должна указывать canonical на основную версию. Подробно эта механика разобрана в материале про canonical и дубли.
Ленивая загрузка, краулинговый бюджет и стратегия
Ленивая загрузка (lazy load) — мощный инструмент скорости, но в SEO её нужно применять осторожно. Lazy load изображений ниже первого экрана — это хорошо и поддерживается нативно через атрибут loading="lazy". А вот ленивая загрузка основного текстового контента или товаров по событию скролла — плохо: робот не скроллит так, как человек, и может не догрузить контент. Правило простое: всё, что должно ранжироваться, должно присутствовать в DOM без пользовательских действий.
Краулинговый бюджет на JS-сайтах расходуется быстрее. Каждая страница, требующая рендеринга, нагружает очередь сильнее обычной. На крупном каталоге это приводит к тому, что часть страниц робот просто не успевает обработать. SSR и SSG снимают эту нагрузку: роботу достаётся готовый HTML, рендерить ничего не нужно, бюджет тратится эффективнее. Грамотная перелинковка и аккуратный sitemap дополнительно помогают роботу находить и приоритизировать важные страницы.
Как выбрать стратегию рендеринга на практике? Отталкивайтесь от типа контента. Контент меняется редко и его много — SSG. Контент динамический, важна актуальность, аудитория в рунете — SSR. Раздел не нужен в поиске — CSR. Часто оптимальна гибридная схема: витрина, каталог и блог на SSR/SSG ради SEO, а личный кабинет на CSR. Пока вы перестраиваете рендеринг и ждёте переиндексации, трафик можно подстраховать контекстной рекламой — она приводит посетителей сразу, не дожидаясь, пока поисковик разберётся с вашим JavaScript. Примеры того, как мы выводили JS-проекты в ТОП, собраны в портфолио.
Чек-лист JS-SEO перед запуском
Контент в исходном HTML
Основной текст, H1 и ссылки видны по Ctrl+U без исполнения скриптов. Проверено и в Google, и в Яндексе.
Честные ссылки и ЧПУ
Вся навигация — через <a href> с нормальными адресами, без onclick и без hash-роутинга через #.
Уникальные метатеги на каждый роут
Title, description и canonical меняются при смене маршрута и попадают в серверный HTML, а не проставляются скриптом.
Открытые JS и CSS в robots.txt
Робот должен иметь доступ к скриптам и стилям, чтобы корректно отрендерить страницу.
Корректные коды ответа
Несуществующие страницы отдают честный 404, а не пустышку с кодом 200. Никаких soft 404.
Скорость и Core Web Vitals
Бандл оптимизирован, гидрация быстрая, метрики LCP, INP и CLS в зелёной зоне.
Частые вопросы
В Google — с оговорками и задержкой, в Яндексе — практически нет. Чистый CSR оставляет роботу пустую оболочку, и для рунета это почти гарантированная потеря индексации. Если нужен органический трафик, добавляйте SSR (Next.js) или статическую генерацию. Чистый CSR оправдан только для закрытых разделов вроде личного кабинета, которым поиск не нужен.
SSR собирает HTML на сервере при каждом запросе — подходит для динамического контента (каталоги, цены, остатки). SSG генерирует HTML заранее на этапе сборки — идеально для контента, который меняется редко (блог, лендинги, услуги). SSG быстрее и дешевле в обслуживании, SSR гибче для динамики. Часто их комбинируют в одном проекте по типам страниц.
Откройте страницу и нажмите Ctrl+U — это исходный HTML, который получает робот. Найдите в нём основной текст и H1. Если контента там нет, а в инструментах разработчика (F12) он есть — значит, страница рендерится на клиенте и под угрозой. Дополнительно используйте «Проверку URL» в Search Console и сохранённую копию в выдаче Яндекса.
В одностраничном приложении при смене роута метатеги по умолчанию не обновляются — робот видит title и description главной на всех внутренних страницах. Нужно управлять метатегами на смену маршрута (react-helmet, средства Next.js, плагины Nuxt) и, что важно, выводить их в серверном HTML, а не проставлять скриптом после загрузки, иначе «слабый» робот их не увидит.
Продвинем сайт на JavaScript и выведем в ТОП
Настроим рендеринг, индексацию и техническую базу сайта на React, Vue или SPA. Уберём проблемы JS-SEO и приведём трафик. Прозрачный договор, отчёты каждую неделю.
- Пакет «Старт» от 55 000 ₽/мес
- Пакет «Стандарт» 75 000 ₽/мес
- Пакет «Премиум» 95 000 ₽/мес
- Бесплатный аудит и прогноз
- Договор с гарантией результата
- Отчёты каждую неделю
Комментарии (17)
roman_seo
Наконец-то внятная статья про SPA. Сделали сайт на React без SSR, полгода Google вообще не индексировал внутренние страницы. Прикрутили prerender.io — за месяц в индекс зашло 340 страниц из 380.
AdminSEO Мастер
Роман, отличный результат! Prerender действительно спасает, но на перспективу лучше смотреть в сторону SSR или SSG — так вы уберёте зависимость от стороннего сервиса и ускорите отдачу контента.
Марина_К
А как проверить, видит ли Гугл контент, который подгружается через JS?
AdminSEO Мастер
Марина, откройте инструмент проверки URL в Search Console и посмотрите отрендеренный HTML во вкладке скриншота и кода. Если контента там нет — значит бот его не получает.
Дмитрий
Мы на Vue сделали SSR через Nuxt и разом закрыли большинство проблем с индексацией. Рекомендую всем, кто только стартует.
Аня_дизайнер
Не совсем поняла разницу между SSR и пререндером, можете в двух словах?
AdminSEO Мастер
Аня, при SSR сервер собирает HTML на каждый запрос динамически, а пререндер отдаёт заранее сгенерированные статические страницы ботам. Для контентных проектов чаще достаточно пререндера или SSG.
Игорь77
Screaming Frog в режиме рендеринга JavaScript очень помог отловить, какие страницы отдают пустой body. Без него бы копались вслепую.
Оксана
У нас после перехода на клиентский рендеринг просели позиции почти в ноль. Хорошо, что вовремя нашли причину.
Костя_маркетолог
Спорно про то, что Яндекс хуже рендерит JS. По моим наблюдениям он вполне сносно справляется с современными фреймворками, просто медленнее.
AdminSEO Мастер
Константин, отчасти согласен, Яндекс подтянулся за последние годы. Но задержка рендеринга у него всё равно ощутимо больше, поэтому критичный контент безопаснее отдавать в готовом HTML.
Павел Р.
Добавлю от себя: следите за тем, чтобы ссылки были настоящими тегами a с href, а не onClick на div. Боты по кликам не ходят.
Света_Пермь
Спасибо, отправила статью разработчикам, а то они мне доказывали, что SEO для SPA не нужно.
Вадим
Как быть с ленивой подгрузкой контента при скролле? Гугл же не скроллит страницу.
AdminSEO Мастер
Вадим, для важного контента лениво подгружать нельзя — либо отдавайте его сразу в HTML, либо используйте подход с загрузкой по пагинации со ссылками. То, что появляется только при скролле, бот может не увидеть.
Наталья
После внедрения динамического рендеринга для ботов трафик из поиска вырос на 60% за квартал. Метрика показывает стабильный рост.
Артём
Мета-теги на SPA — отдельная боль. Пока не поставили vue-meta, у всех страниц был один title.
Людмила
А hydration ошибки влияют на SEO? У нас в консоли их полно.
Сергей_В
Пробовали Next.js с ISR — сочетание статики и актуальности контента идеально зашло под большой каталог.
Кирилл
Полезно, но хотелось бы больше про измерение скорости рендеринга через Lighthouse.
Эльвира
У нас интернет-магазин на Angular, фильтры генерировали кучу мусорных URL. Закрыли через canonical и параметры — стало намного чище.
monkey_dev
Совет из практики: тестируйте отрендеренную версию через Mobile-Friendly Test, там сразу видно итоговый HTML, который получает бот.