JavaScript и индексация сайта: как поисковые роботы видят динамический контент
Александр Каширин
August 25, 2026
JavaScript сам по себе не мешает продвижению. Проблемы начинаются, когда поисковый робот получает пустой HTML, не может загрузить ресурсы, не видит обычных ссылок, сталкивается с ошибкой API или получает метатеги, отличающиеся от тех, что видит пользователь. В браузере страница может выглядеть идеально, но в поисковой системе оказаться пустой, дублирующей или неизвестной.
Google и Яндекс умеют выполнять JavaScript, однако рендеринг требует дополнительных ресурсов и происходит не так, как просмотр человеком. Надёжная SEO-архитектура не строится на предположении «робот всё отрисует», а обеспечивает полезный HTML, устойчивые URL и одинаковые сигналы на каждом этапе.
В руководстве разберём CSR, SSR, SSG, SPA-маршруты, lazy loading, canonical, noindex, Soft 404 и диагностику от исходного ответа до отрисованного DOM. Если URL уже отсутствует в поиске, сначала используйте инструкцию как проверить индексацию страницы и перечень причин, почему страницы сайта не индексируются.
Содержание
- Что такое JavaScript SEO
- Как Google обрабатывает JavaScript
- Как Яндекс рендерит JavaScript
- CSR, SSR, SSG и гибридный рендеринг
- Как выбрать способ рендеринга
- Диагностика одной страницы
- Исходный HTML и отрисованный DOM
- Ссылки и обнаружение URL
- SPA, маршруты и HTTP-коды
- Canonical, robots и метаданные
- Структурированные данные и AI-поиск
- Lazy loading и контент после действий
- API, ресурсы и ошибки JavaScript
- Дубли и параметры
- Скорость и краулинговый бюджет
- Gatsby, React и Next.js
- Массовый аудит
- План исправления
- Практические сценарии
- Интернет-магазины и каталоги
- Миграция на JavaScript-фреймворк
- Мониторинг после исправления
- Типичные ошибки
- Чек-лист
- FAQ
- Вывод
Что такое JavaScript SEO
JavaScript SEO — часть технической оптимизации, которая помогает поисковому роботу обнаружить URL, загрузить ресурсы, получить итоговый контент и правильно понять страницу. Это контроль всей цепочки:
- робот находит URL;
- сервер отвечает подходящим HTTP-кодом;
- исходный HTML содержит или позволяет получить основной документ;
- CSS, JavaScript и API доступны;
- приложение завершается без критической ошибки;
- отрисованный DOM содержит текст, ссылки и метаданные;
- поисковая система выбирает canonical и решает, включать ли страницу в индекс.
Сбой на любом этапе меняет результат. Страница может быть обнаружена через Sitemap, но не отрисоваться. Может отрисоваться, но создать второй canonical. Может содержать товар, но возвращать 200 для несуществующих карточек. Поэтому проверять только внешний вид недостаточно.
Обычная серверная страница также использует JavaScript: меню, калькулятор или форма не превращают её в клиентское приложение. SEO-риск зависит от того, какие элементы формируются скриптами. Низкий риск — основной текст, title, canonical и ссылки уже находятся в HTML. Высокий риск — сервер отдаёт один пустой контейнер, а всё полезное появляется после нескольких запросов API.
Главный вопрос: что останется на странице, если основной JavaScript не выполнится или API ответит с задержкой?
Как Google обрабатывает JavaScript
Google описывает связанные стадии обхода, рендеринга и индексирования. При первом запросе Googlebot получает HTTP-ответ и исходный HTML. Из обычных ссылок с атрибутом href он может сразу извлечь новые URL. Страницы с ответом 200 обычно направляются в очередь рендеринга, если индексирование не запрещено.
Когда ресурсы доступны, Web Rendering Service запускает headless Chromium, выполняет JavaScript и создаёт отрисованный HTML. Google повторно анализирует DOM, находит добавленные ссылки и использует результат для индексирования.
Практические последствия:
- рендеринг может происходить не одновременно с первым обходом;
- не каждый запрос приложения обязательно будет выполнен;
- несущественные ресурсы могут не загружаться;
- страница с noindex в исходном HTML может не дождаться выполнения кода;
- ответы, отличные от 200, могут не рендериться;
- индексирование не гарантируется после успешного рендеринга.
Google рекомендует серверный рендеринг или пререндеринг как надёжный вариант: это быстрее для пользователей и роботов, а не все поисковые, социальные и AI-боты выполняют JavaScript.
Очередь рендеринга не нужно воспринимать как гарантированную «вторую волну» через фиксированное время. Важная информация должна быть доступна максимально рано, а результат не должен зависеть от случайной последовательности запросов.
Как Яндекс рендерит JavaScript
Яндекс Вебмастер содержит инструмент Индексирование → Рендеринг страниц JavaScript. По умолчанию используется вариант «На усмотрение робота Яндекса»: система может сравнивать полноту страницы с выполнением и без выполнения кода.
Если сайт использует SSR или пререндеринг и исходный HTML уже полноценный, Яндекс рекомендует запретить дополнительный рендеринг. Это может уменьшить нагрузку на сервер. Для CSR-сайта, где содержание появляется только после выполнения кода, рендеринг должен оставаться доступным.
Порядок проверки:
- откройте Индексирование → Проверка страницы;
- укажите URL и мобильную либо десктопную версию;
- дождитесь результата;
- сравните версию в базе, внешний вид и доступный контент;
- в инструменте рендеринга сравните страницу с JavaScript и без него.
Яндекс поддерживает объект window.YandexRotorSettings для страниц с отложенной загрузкой. Через него можно сообщить о завершении загрузки или ошибке. Механизм полезен, когда ожидание действительно необходимо, но не заменяет стабильный HTML.
Не включайте фиксированное ожидание «на всякий случай». Надёжнее проверять появление конкретного элемента или явное состояние приложения. Если документ можно сформировать на сервере или при сборке, архитектура будет проще.
CSR, SSR, SSG и гибридный рендеринг
| Подход | Где формируется основной HTML | Преимущество | Основной риск |
|---|---|---|---|
| CSR | в браузере после JavaScript | интерактивное приложение | пустой исходный HTML, зависимость от API |
| SSR | на сервере для запроса | актуальный готовый документ | нагрузка и ошибки сервера |
| SSG | во время сборки | быстрый стабильный HTML | устаревание и ошибки сборки |
| Гибридный | зависит от страницы | баланс скорости и актуальности | сложность правил |
Client-Side Rendering
Сервер отдаёт оболочку, JavaScript загружает данные и создаёт DOM. Это подходит для закрытых кабинетов, но публичные посадочные требуют особенно тщательного тестирования. Если API недоступен, робот получает оболочку вместо документа.
Server-Side Rendering
Сервер формирует HTML при запросе. Робот и пользователь получают содержание сразу, затем JavaScript гидратирует интерактивные элементы. Ошибка SSR должна возвращать корректный статус, а не пустую страницу с 200.
Static Site Generation
HTML создаётся заранее. Для статей, услуг и стабильных категорий это надёжный вариант. Риск возникает, когда новая страница не включена в сборку, данные устарели или production build завершился не полностью.
Гибридная архитектура
Современные фреймворки позволяют статически генерировать часть сайта, рендерить динамические страницы на сервере и оставлять клиентскими личные разделы. Метод выбирают по интенту и частоте обновления, а не один режим для всего проекта.
Как выбрать способ рендеринга
Для страницы услуги, статьи, категории и карточки товара поисковый контент должен присутствовать в первоначальном ответе или гарантированно формироваться на сервере. Для кабинета, конструктора или внутреннего отчёта индексация обычно не нужна, поэтому CSR не создаёт SEO-проблемы.
Задайте четыре вопроса:
- Нужен ли URL в органическом поиске?
- Как часто меняется основной контент?
- Может ли сервер или сборка сформировать его без браузера?
- Что увидит пользователь и робот при отказе API?
SSG удобен для редакционных материалов. SSR — для часто меняющихся листингов. CSR — для интерактивности после отображения основной информации. Гибридный подход позволяет не превращать SEO в ограничение продукта.
Не выбирайте SSR только потому, что он считается «SEO-дружественным». Плохо настроенный SSR возвращает 500, увеличивает задержку и создаёт нестабильные страницы. Сравнивайте риски, нагрузку, свежесть и стоимость поддержки.
Диагностика одной JavaScript-страницы
Шаг 1. Проверьте HTTP
Для индексируемого URL ожидается прямой 200. Найдите лишние редиректы, неправильный Content-Type, X-Robots-Tag и периодические 5xx. Проверьте ответ обычному браузеру и поисковому роботу.
Шаг 2. Получите исходный HTML
Проверьте title, description, H1, основной текст, canonical, robots и ссылки. Если видна только оболочка, зафиксируйте это как риск, но не считайте автоматически ошибкой.
Шаг 3. Получите отрисованную версию
Используйте проверку URL в Search Console, Rich Results Test, Яндекс Вебмастер и браузер с отключённым кэшем. Сравните текст, DOM, ресурсы и ошибки консоли.
Шаг 4. Проверьте ресурсы
JS-бандлы, CSS, API, шрифты и изображения должны загружаться без 403, 404, 429 и 5xx. Проверьте CORS, cookie, авторизацию и ограничения CDN.
Шаг 5. Сопоставьте с индексом
Успешный скриншот не доказывает выбор правильного URL. Проверьте canonical, статус индексирования, дату обхода и сохранённую версию.
Исходный HTML и отрисованный DOM
| Элемент | Исходный HTML | После рендеринга | Ожидаемый результат |
|---|---|---|---|
| Title | значение | значение | одинаковый смысл |
| H1 | есть или нет | значение | один основной заголовок |
| Текст | объём | объём | ключевой контент доступен |
| Canonical | URL | URL | нет конфликтной замены |
| Robots | значение | значение | нет случайного noindex |
| Ссылки | количество | количество | важные URL обнаружимы |
| JSON-LD | есть или нет | валидность | соответствует странице |
Опасны не любые различия, а изменения смысла. Интерактивная цена может обновиться после загрузки. Но если после рендеринга статья превращается в ошибку, canonical уходит на главную или весь текст исчезает, индексирование нестабильно.
Проверяйте несколько повторов. Ошибка API может проявляться только при холодном кэше, высокой нагрузке или определённом регионе. Один успешный тест не отменяет данные серверных логов.
Ссылки и обнаружение URL
Используйте обычный элемент a с атрибутом href. Google и Яндекс извлекают URL именно из адреса ссылки. Кнопка с onclick, элемент div или ссылка через фрагмент не создают надёжную навигацию.
Для SPA используйте History API и отдельные URL без решётки. Каждый индексируемый экран должен:
- иметь самостоятельный адрес;
- открываться напрямую;
- переживать перезагрузку браузера;
- возвращать правильный HTTP-ответ;
- содержать уникальные метаданные;
- получать обычные внутренние ссылки.
Sitemap помогает сообщить адреса, но не заменяет архитектуру. Страница без внутренних ссылок остаётся слабосвязанной. Подробнее — в руководстве по Sitemap XML.
SPA, маршруты и HTTP-коды
Типичная SPA возвращает одинаковую оболочку с 200 для любого пути, включая несуществующий. После выполнения JavaScript пользователь видит «страница не найдена», но робот сначала получает успешный ответ. Так появляется Soft 404.
Надёжные варианты:
- сервер возвращает 404 для несуществующего маршрута;
- приложение перенаправляет на URL, который отдаёт серверный 404;
- для клиентской страницы ошибки добавляется noindex, если серверный статус изменить невозможно.
Для существующих маршрутов прямой запрос должен отдавать правильную страницу, а не серверный 404 с последующим восстановлением JavaScript. Проверьте глубокие URL после production deploy.
Редиректы в JavaScript используйте только когда серверный вариант невозможен. Они обрабатываются позже и усложняют диагностику. При постоянной смене адреса предпочтителен серверный 301.
Canonical, robots и динамические метаданные
Google рекомендует задавать canonical в исходном HTML и не менять его JavaScript на другое значение. Если серверный canonical невозможен, оставьте его вне исходного HTML и добавьте один согласованный тег после рендеринга. Два конфликтующих canonical создают неопределённость.
Не помещайте noindex в исходную оболочку с планом удалить его JavaScript. Google может не выполнять код после обнаружения запрета. Индексируемая страница должна быть разрешена с первого ответа.
Проверьте:
- уникальный title и description;
- один canonical;
- отсутствие noindex;
- одинаковые данные в мобильной и десктопной версии;
- валидный JSON-LD, соответствующий видимому контенту;
- правильный URL в Open Graph и schema;
- отсутствие смены метатегов при ошибке гидратации.
Подробности есть в статьях про canonical и про noindex.
Структурированные данные, GEO и AI-поиск
JavaScript-сайт должен передавать поисковым и AI-системам не отдельный набор SEO-тегов, а согласованный документ. Заголовок, видимый текст, canonical, автор, дата, организация и JSON-LD не должны противоречить друг другу.
Google поддерживает структурированные данные, созданные JavaScript, но динамическая генерация добавляет точку отказа. Если выполнение прерывается, разметка исчезает. Для статей, услуг, организации и хлебных крошек надёжнее включать JSON-LD в серверный или статический HTML.
Что проверить в разметке
- URL сущности совпадает с canonical;
- заголовок и описание соответствуют видимому тексту;
- дата публикации и изменения реальны;
- автор и издатель существуют на сайте;
- изображение доступно роботу;
- цена и наличие не расходятся с карточкой;
- BreadcrumbList повторяет реальную навигацию;
- FAQ содержит только видимые вопросы и ответы;
- разметка не исчезает при ошибке гидратации.
Не создавайте schema в системе тегов отдельно от данных страницы. Два источника быстро расходятся: приложение покажет новую цену, а JSON-LD сохранит старую; редактор поменяет автора, а клиентский скрипт продолжит выводить прежнего.
Понятная структура важнее специальных «AI-тегов»
Для генеративного поиска полезна та же техническая основа: доступный HTML, ясная иерархия H1–H3, однозначные сущности, авторство, даты, внутренние ссылки и подтверждаемые факты. Не существует универсального метатега, который гарантирует цитирование в AI-ответах.
Делайте ключевые определения самостоятельными и понятными без контекста интерфейса. Таблицы должны иметь заголовки, изображения — осмысленный alt, а интерактивные калькуляторы — текстовое объяснение методики. Если ответ существует только после клика или внутри canvas, системе сложнее извлечь его как документ.
Социальные и вспомогательные боты
Не все боты выполняют JavaScript так же, как Google. Поэтому Open Graph, Twitter Cards, canonical и основное изображение лучше отдавать сразу. Это влияет на превью в мессенджерах и снижает риск того, что внешняя система увидит пустую оболочку.
После внедрения проверьте не только валидатор, но и HTML production-страницы. Валидная разметка не исправляет отсутствие контента, неправильный canonical или noindex.
Lazy loading и контент после действий
Отложенная загрузка изображений и второстепенных блоков полезна для скорости, если срабатывает при приближении к области просмотра. Поисковый робот не обязан нажимать кнопку, прокручивать карусель, выбирать вкладку или вводить данные.
Не прячьте за взаимодействием:
- основной текст;
- ссылки пагинации;
- карточки каталога;
- важные изображения;
- характеристики товара;
- отзывы, необходимые для понимания предложения.
Аккордеон допустим, если содержание уже находится в HTML или DOM и скрывается визуально. «Показать ещё», которое делает новый API-запрос, требует отдельной проверки. Для длинного списка создайте доступную пагинацию или устойчивые URL.
API, ресурсы и ошибки JavaScript
Основные причины:
- JS-бандл заблокирован или отсутствует;
- API возвращает 401, 403, 429 или 5xx;
- CORS не разрешает запрос;
- код зависит от localStorage или cookie;
- функция браузера не поддерживается;
- выполнение завершается исключением;
- загрузка занимает слишком долго;
- CDN отдаёт старую несовместимую версию.
Используйте content hashing для файлов сборки, чтобы новый HTML ссылался на правильный бандл. Сохраняйте логи ошибок приложения и API. Клиентская аналитика не показывает всю активность рендерера поисковой системы.
Состояние отказа должно быть понятным: корректный HTTP-код или серверный минимальный документ. Пустая страница с 200 — худший вариант, потому что выглядит успешной технически.
Не маскируйте ошибки от робота другим содержимым. Пользователь и поисковая система должны получать эквивалентный документ. Отдельная упрощённая версия допустима как результат рендеринга, но не как скрытая подмена ради SEO.
Дубли, параметры и клиентское состояние
Фильтры SPA часто создают множество URL через параметры. Определите, какие комбинации являются самостоятельными посадочными. Остальные не должны попадать во внутренние ссылки и Sitemap.
Следите, чтобы сортировка, модальные окна, вкладки и состояние интерфейса не создавали индексируемые дубли. Для значимого контента используйте отдельный устойчивый URL; для временного состояния — не создавайте новый адрес.
Canonical, внутренние ссылки и Sitemap должны указывать на одну версию. Если контент меняется без изменения URL, поисковик не сможет хранить отдельные состояния как документы. Если URL меняется, а содержимое остаётся одинаковым, образуется кластер дублей.
Скорость, рендеринг и краулинговый бюджет
Тяжёлый JavaScript влияет и на пользователей, и на обработку роботом. Сократите бандлы, разбивайте код по маршрутам, удаляйте неиспользуемые зависимости и не делайте каскад последовательных API-запросов.
Для крупных сайтов рендеринг тысяч слабых параметров расходует ресурсы. Сначала ограничьте генерацию URL, улучшите сервер и перелинковку. Отдельная методика описана в статье про краулинговый бюджет.
Core Web Vitals и индексирование — разные задачи. Быстрая страница может быть закрыта noindex, а медленная — индексироваться. Но общая архитектурная причина часто влияет на оба направления: большой бандл задерживает пользователя, усложняет рендеринг и повышает вероятность ошибки.
Gatsby, React и Next.js
Gatsby
Проверьте, что страница создаётся production-сборкой, доступна по ожидаемому slug и содержит HTML до гидратации. Ошибка GraphQL или изображения может остановить генерацию. После gatsby build откройте итоговую страницу через gatsby serve, а не только develop.
Для данных, доступных только в браузере, предусмотрите серверный или сборочный источник. Не используйте window во время SSR без проверки окружения. Убедитесь, что гидратация не заменяет готовый текст пустой оболочкой.
React SPA
Добавьте серверную обработку маршрутов, корректные статусы и обычные ссылки. Для публичных посадочных рассмотрите SSR, SSG или пререндеринг. Не формируйте все метатеги только после нескольких запросов.
Next.js
Выберите статическую генерацию для стабильных страниц, SSR — для актуальных данных, клиентские компоненты — для интерактивности. Проверьте metadata API, обработку notFound, canonical и согласованность серверного и клиентского HTML.
WordPress с JavaScript-фильтрами
Сам WordPress обычно отдаёт HTML, а риск создаёт фильтр товаров или конструктор. Проверьте, что категории и пагинация доступны обычными ссылками, а фильтрация не создаёт бесконечные параметры. Основной текст не должен исчезать до загрузки плагина.
Массовый аудит JavaScript-сайта
Выберите образцы всех шаблонов: главная, услуга, категория, товар, статья, пагинация, фильтр и 404. Для каждого сохраните:
- HTTP-код;
- размер исходного HTML;
- текст до и после рендеринга;
- title, robots и canonical;
- число ссылок;
- ошибки ресурсов;
- состояние в Google и Яндексе;
- время получения основного контента.
Crawler без JavaScript покажет базовый HTML, а crawler с Chromium — отрисованный DOM. Разница между выборками выявляет системные проблемы. Не запускайте тяжёлый рендеринг всех URL, пока не проверили несколько шаблонов.
Группируйте ошибки по причине. Тысяча пустых карточек с одним шаблоном — одна задача разработчика. Отдельно приоритизируйте URL с трафиком, коммерческие категории, статьи со ссылками и страницы, недавно выпавшие из индекса.
Пошаговый план исправления
- Определите индексируемые типы страниц.
- Проверьте HTTP и прямое открытие маршрутов.
- Сравните исходный HTML и DOM.
- Исправьте ссылки без href.
- Перенесите критический контент в SSR или SSG.
- Согласуйте canonical, robots и Sitemap.
- Настройте 404 и ошибки API.
- Разрешите необходимые ресурсы.
- Проверьте production-сборку.
- Отправьте несколько исправленных URL на переобход.
- Наблюдайте за логами, статусами и показами.
Не мигрируйте весь сайт на новый фреймворк без доказанной причины. Иногда достаточно исправить шаблон ссылок, убрать noindex из оболочки или вернуть правильный статус.
После первой правки тестируйте ограниченную группу. Если результат подтверждён в Google и Яндексе, распространяйте изменение на шаблон. Это безопаснее массового релиза без сравнения.
Практические сценарии
Категория видна пользователю, но пуста для робота
Сервер отдаёт заголовок и контейнер, товары загружаются после API. В проверке URL API отвечает 403. Разрешите запрос рендереру и, надёжнее, выведите первый листинг сервером. Пагинация должна иметь обычные ссылки.
После релиза страницы стали дублями
Новый шаблон сначала отдаёт canonical главной, затем JavaScript меняет его. Робот получает конфликт. Исправьте серверную генерацию canonical и не изменяйте его клиентом.
Несуществующие товары возвращают 200
SPA показывает «товар не найден», но сервер всегда успешен. Настройте 404 на уровне маршрута либо переход на серверную страницу ошибки. Уберите такие URL из Sitemap.
Статья появляется только после прокрутки
Lazy loading привязан к пользовательскому событию. Перенесите основной текст в HTML; отложенно загружайте тяжёлые изображения и второстепенные виджеты.
Страница индексируется без части характеристик
Первый API-запрос возвращает товар, второй — параметры. Рендерер завершает обработку раньше второго ответа. Объедините критические данные в серверный документ или основной запрос. Не заставляйте робота собирать страницу из длинной цепочки зависимостей.
После сборки Gatsby URL отсутствует
В develop маршрут создаётся динамически, а production build не получил данные GraphQL. Исправьте источник и остановите публикацию при ошибке сборки. Наличие ссылки не создаст отсутствующий HTML-файл.
JavaScript в интернет-магазинах и каталогах
Магазин сочетает почти все зоны риска: карточки получают данные из API, фильтры меняют URL, наличие обновляется в браузере, а пагинация может работать бесконечной прокруткой. Поэтому аудит проводят не по одной странице, а по типам и состояниям.
Категории и листинги
Первый набор товаров, название категории, описание и ссылки на подкатегории желательно отдавать в HTML. Пользователь может получить более свежие цены после гидратации, но робот не должен зависеть от прокрутки, чтобы увидеть сам ассортимент.
Бесконечная прокрутка удобна как интерфейс, если дополнена доступной пагинацией. Каждый индексируемый сегмент должен иметь URL и ссылку с href. Если новые товары появляются только после события scroll и отдельного запроса, робот может увидеть лишь первый экран.
Проверяйте пустые состояния. Категория с временно отсутствующими товарами может сохранять 200, полезное описание, альтернативы и ссылки. Ликвидированный раздел должен перенаправляться на релевантную замену или возвращать 404/410. Нельзя показывать одинаковую пустую оболочку на сотнях адресов.
Фильтры
Разделите фильтры на посадочные и пользовательские. Посадочная комбинация соответствует поисковому спросу, имеет стабильный URL, уникальные метаданные, товары и внутренние ссылки. Пользовательская сортировка не нуждается в индексации.
JavaScript не должен создавать новый URL при каждом выборе, если состояние не имеет самостоятельной ценности. Иначе робот обнаружит тысячи комбинаций цены, цвета, размера и порядка сортировки. Это увеличивает обход и формирует дубли.
Для индексируемых фильтров проверьте:
- прямое открытие URL;
- серверный или статический HTML;
- self-canonical;
- уникальный title и H1;
- наличие товаров без клика;
- ссылки из родительской категории;
- отсутствие параметров с тем же содержанием.
Карточка товара
В исходном или серверном HTML должны быть название, описание, ключевые характеристики, цена или понятное состояние, canonical и Product-разметка. Если цена и наличие быстро меняются, они могут обновляться клиентом, но структурированные данные должны соответствовать видимой версии.
Google предупреждает, что динамически созданная товарная разметка может обрабатываться менее регулярно для быстро меняющихся данных. Практический вывод — критичные коммерческие сведения надёжнее формировать сервером и проверять после каждого изменения шаблона.
Варианты товара требуют осознанной модели URL. Если цвет или размер не имеет отдельного спроса и содержания, не создавайте индексируемый дубль. Если вариант является самостоятельным товаром, обеспечьте уникальные данные, URL и согласованный canonical.
Корзина и личный кабинет
Эти страницы не обязаны индексироваться и могут оставаться CSR. Ограничьте их от поиска, не добавляйте в Sitemap и не позволяйте параметрам сессии попадать во внешние ссылки. Никогда не помещайте персональные данные в предварительно отрендеренный публичный HTML.
Миграция сайта на JavaScript-фреймворк
Переход с серверного CMS-сайта на React, Next.js или другой стек часто сопровождается падением не из-за самого фреймворка, а из-за одновременной смены URL, HTML, метаданных, перелинковки и серверной конфигурации.
До миграции
Сохраните контрольный список старых URL и данные:
- HTTP-коды;
- title, description и H1;
- canonical и robots;
- основной текст;
- внутренние ссылки;
- структурированные данные;
- трафик, показы и позиции;
- страницы с внешними ссылками;
- содержимое Sitemap.
Выделите шаблоны и приоритетные страницы. Новый сайт тестируют сравнением, а не впечатлением от дизайна.
На тестовом контуре
Закройте staging авторизацией, но убедитесь, что production-конфигурация не унаследует noindex. Проверьте маршруты напрямую, 404, редиректы и итоговый HTML. Выполните production build в среде, максимально близкой к серверу.
Для каждой группы сравните старую и новую страницу. Снижение объёма HTML допустимо, если полезный контент сохранён. Исчезновение ссылок, заголовков или schema — регрессия.
При запуске
Сохраняйте URL, если нет причины менять их. Для изменённых адресов настройте один прямой 301 на максимально близкую страницу. Обновите Sitemap, canonical, hreflang, внутренние ссылки и внешние интеграции.
Не запускайте одновременно новый домен, новую структуру и полностью клиентский рендеринг без поэтапного тестирования. При проблеме будет невозможно быстро отделить причину.
После запуска
Отслеживайте:
- ошибки сборки и SSR;
- 404 и цепочки редиректов;
- запросы Googlebot и YandexBot;
- рост исключённых страниц;
- расхождение canonical;
- снижение проиндексированных URL;
- изменение поисковых запросов и трафика.
Первые дни особенно важны, но окончательные выводы делают после повторного обхода и обновления отчётов. Не откатывайте правильную конфигурацию из-за задержки данных, если живые проверки и логи подтверждают исправность.
Мониторинг после исправления
JavaScript-ошибка может вернуться при следующем релизе, обновлении зависимости или изменении API. Поэтому результат нужно защищать автоматическими и поисковыми проверками.
Проверки в CI
Для приоритетных маршрутов добавьте smoke-тесты:
- production build завершается с кодом успеха;
- ожидаемые HTML-файлы или SSR-маршруты существуют;
- страница возвращает нужный HTTP-код;
- в HTML есть title, H1 и canonical;
- отсутствует noindex;
- ключевые ссылки имеют href;
- не появляется текст ошибки приложения;
- структурированные данные разбираются.
Тесты не заменяют поисковые инструменты, но останавливают очевидную регрессию до публикации.
Синтетический мониторинг
Проверяйте несколько URL каждого шаблона обычным HTTP-запросом и headless-браузером. Сигнализируйте, если изменился статус, пропал текст, выросло время рендеринга или появился JavaScript exception.
Отдельно контролируйте API. Страница может возвращать 200, когда источник данных уже отвечает 500. Пользователь увидит пустой блок, а инфраструктурный мониторинг HTML посчитает сайт доступным.
Серверные логи
Логи показывают, посещают ли роботы URL и получают ли ресурсы. Сегментируйте YandexBot, Googlebot, запросы HTML, JS-бандлов и API. Проверяйте подлинность роботов, если данные используются для решений безопасности.
Ищите повторяющиеся 429, 403, 5xx, длинные ответы и обращения к устаревшим бандлам. Не делайте вывод только по user-agent: сопоставляйте DNS-проверку и официальные рекомендации поисковиков.
Поисковые данные
После релиза проверяйте выборку URL в Search Console и Яндекс Вебмастере, динамику исключений, статусы canonical и сохранённое содержание. Через 30 дней сопоставьте показы, запросы и страницы на позициях 5–20.
Если техническая проверка успешна, а URL не индексируется, не обвиняйте JavaScript автоматически. Причиной могут быть дубли, слабый интент, маловостребованность или отсутствие внутренних ссылок. Вернитесь к общей диагностике и сравните документ с кластером.
Контрольный принцип: мониторинг должен проверять не только доступность URL, но и наличие полезного содержимого после рендеринга.
Типичные ошибки JavaScript SEO
- считать скриншот в браузере доказательством индексации;
- блокировать JS или CSS, необходимые для понимания страницы;
- использовать кнопки вместо ссылок;
- создавать маршруты через решётку;
- возвращать 200 для всех ошибок;
- менять canonical после рендеринга;
- удалять исходный noindex JavaScript-кодом;
- загружать основной контент только после клика;
- полагаться только на Sitemap;
- тестировать develop вместо production build;
- включать dynamic rendering вместо исправления архитектуры.
Google называет dynamic rendering обходным, а не рекомендуемым постоянным решением: он усложняет инфраструктуру и может создавать расхождения между версиями.
Ещё одна ошибка — оценивать все JavaScript-сайты одинаково. Статический Gatsby-блог, серверный Next.js-магазин и закрытая React-панель имеют разные цели. SEO-требования применяются к публичным индексируемым маршрутам.
Чек-лист JavaScript-индексации
- URL нужен в поиске и имеет отдельный интент.
- Прямой запрос возвращает правильный статус.
- Основной контент виден без действий пользователя.
- Title, H1 и description корректны.
- Canonical один и не меняется конфликтно.
- Нет случайного noindex.
- Ссылки используют элемент a и href.
- Глубокие маршруты открываются напрямую.
- Страница ошибки не возвращает 200.
- JS, CSS и API доступны.
- В консоли нет критических ошибок.
- Исходный HTML и DOM сопоставлены.
- URL присутствует в Sitemap.
- На страницу ведут внутренние ссылки.
- Мобильная версия содержит тот же основной контент.
- JSON-LD соответствует видимой странице.
- Production build завершается успешно.
- Результат проверен в Google и Яндекс Вебмастере.
Если проблема затрагивает несколько шаблонов, безопаснее провести технический SEO-аудит или заказать техническую оптимизацию сайта, чем исправлять отдельные URL без поиска системной причины.
Частые вопросы о JavaScript и индексации
Google индексирует JavaScript?
Да. Google выполняет JavaScript через Web Rendering Service и использует отрисованный HTML. Но ошибки, запреты и недоступные запросы могут привести к неполному документу.
Яндекс выполняет JavaScript?
Да. Вебмастер позволяет управлять рендерингом и сравнивать содержимое с выполнением и без выполнения кода. Для SSR и пререндеринга Яндекс рекомендует отключать дополнительный рендеринг.
Обязательно ли переходить на SSR?
Нет. Если CSR-страницы стабильно рендерятся, имеют доступные URL, корректные статусы и метаданные, они могут индексироваться. SSR и SSG снижают зависимость от дополнительного этапа.
Что лучше для SEO: SSR или SSG?
Оба подхода дают готовый HTML. SSG удобен для стабильного контента, SSR — для часто обновляемых данных. Выбор зависит от продукта, нагрузки и свежести.
Может ли JavaScript менять canonical?
Google способен увидеть добавленный тег, но рекомендует задавать canonical в исходном HTML и не менять его на другое значение. Не создавайте два тега.
Почему нельзя убрать noindex скриптом?
Google может прекратить обработку после обнаружения запрета и не выполнить код, который должен его удалить. Индексируемая страница не должна содержать исходный noindex.
Индексируется ли контент после клика?
Рассчитывать на клик нельзя. Робот не обязан взаимодействовать с интерфейсом. Основной контент и ссылки должны появляться без пользовательского действия.
Как проверить, что робот видит текст?
Сравните исходный HTML с DOM в Search Console, Rich Results Test и Яндекс Вебмастере. Проверьте скриншот, HTML, ресурсы и консольные ошибки.
Нужно ли разрешать все JS-файлы?
Не блокируйте ресурсы, необходимые для понимания страницы. Несущественные файлы можно ограничивать, но сначала проверьте итоговый документ.
Что делать со старыми AJAX URL с фрагментами?
Используйте обычные URL и History API. Яндекс рекомендует отказаться от старой схемы escaped fragment и убрать фрагменты из Sitemap и ссылок.
Влияет ли JavaScript на краулинговый бюджет?
Рендеринг требует ресурсов, а бесконечные параметры и тяжёлые страницы увеличивают нагрузку. Оптимизацию начинают с контроля URL, сервера и архитектуры, а не с отказа от JavaScript.
Нужен ли пререндеринг только для роботов?
Отдельная версия только для роботов увеличивает риск расхождений. Предпочтительнее SSR или SSG для всех пользователей. Dynamic rendering оставляют временным обходным решением.
Почему страница появилась в индексе без текста?
Робот мог получить оболочку, ошибку API или раннюю версию DOM. Проверьте сохранённый HTML, дату обхода и повторяемость загрузки. После исправления отправьте URL на переобход.
Вывод: робот должен получить полезный документ
Надёжная JavaScript-индексация строится на простом и проверяемом на практике принципе: поисковый робот открывает устойчивый URL, получает корректный HTTP-ответ, видит основной контент и ссылки, а после рендеринга не обнаруживает конфликтующих метатегов или ошибок.
Используйте JavaScript для интерфейса, но не делайте индексируемую страницу зависимой от случайного клика, недоступного API и смены canonical. Для важных посадочных выбирайте SSR, SSG или гибридную архитектуру, проверяйте production-версию и сравнивайте исходный HTML с отрисованным DOM.
Начинайте не с переписывания приложения, а с измерения: выберите важный шаблон, получите серверный ответ, отрисуйте страницу инструментами поисковиков и найдите первое реальное расхождение. Исправление одной доказанной причины обычно полезнее масштабной миграции «для SEO». После подтверждения результата распространите решение на одинаковые шаблоны, добавьте автоматическую проверку в сборку и назначьте повторный контроль индексации. Так JavaScript остаётся инструментом продукта, а техническая архитектура — предсказуемой для пользователей, поисковых систем и внешних сервисов.
Источники
- JavaScript SEO basics — Google Search Central
- Fix Search-related JavaScript problems — Google Search Central
- Dynamic rendering as a workaround — Google Search Central
- Fix lazy-loaded content — Google Search Central
- Индексирование страниц с JavaScript — Яндекс Вебмастер
- Как поиск и посетители видят страницы сайта — Яндекс Вебмастер
- Индексирование AJAX-сайтов — Яндекс Вебмастер

