Значение и границы
При CSR сервер может вернуть облегчённую HTML-оболочку, а содержимое браузер получает или собирает через JavaScript. Такой подход уместен в приложениях с большим количеством интерактива, но он создаёт дополнительную цепочку зависимостей: HTML, скрипты, API и логика рендеринга должны работать, чтобы и сканер, и посетитель получили одно и то же важное содержимое.
Практический порядок работы
Начните с того, что нужно пользователю и сканеру. Выясните, есть ли в исходном HTML title, основной текст, canonical, директивы robots, внутренние ссылки, изображения и структурированные данные или они появляются только после выполнения JavaScript. Если критичный для обнаружения контент отложен, выберите архитектуру, которая надёжно его отдаёт: серверный рендеринг, статическую генерацию или проверенный гибридный подход.
Что проверять
Сравните сырой HTML-ответ с результатом проверки отрисованной страницы на репрезентативной выборке шаблонов. Убедитесь, что JavaScript-ресурсы не заблокированы, запросы данных проходят без приватной сессии, canonical остаётся стабильным и состояния ошибок не подменяют основное содержимое. Google советует тестировать JavaScript-приложения, а не полагаться на то, что название фреймворка гарантирует сканируемость.
Ограничения и частые ошибки
Не считайте CSR автоматически вредным для SEO и не предполагайте, что сканер ничего не видит. Полезный вопрос: нужные содержимое и метаданные стабильно доступны после реального пути рендеринга? Отдельный сценарий только для ботов не делайте, если он не остаётся равнозначным и поддерживаемым.
Проверки рендеринга на конкретном примере маршрута
Возьмите маршрут вроде /guides/rendering. Запросите его без состояния браузера и сохраните тело ответа. Затем откройте тот же маршрут в чистой сессии браузера и посмотрите отрисованный DOM, консоль и вкладку Network. Два представления не обязаны совпадать байт в байт, но назначение маршрута должно сохраниться: полезный title, главный заголовок, основной текст, canonical, доступные для сканирования ссылки и важные структурированные данные должны появляться без авторизованного API-запроса, гонки таймингов или исключения на стороне клиента.
<a href="/guides/rendering">Rendering guide</a>\n<link rel="canonical" href="https://example.test/guides/rendering">В сценарии сбоя app shell исходный HTML может содержать только корневой элемент, а запрос данных завершается ошибкой 401, 403, 404 или исключением JavaScript. Человек после входа может видеть закешированную страницу, а чистый рендерер увидит пустую оболочку. Правильный ход — не выдавать такой маршрут за успешный ответ 200, а классифицировать путь ошибки и либо сделать нужные публичные данные доступными этому маршруту, либо выбрать серверный или статический рендеринг для контента, который должен отдаваться сразу.
Google описывает конвейер сканирования, рендеринга и индексации JavaScript-страниц. Ответ 200 может попасть в очередь рендеринга, но заблокированные страницы и заблокированные JavaScript-ресурсы не рендерятся. Google также рекомендует инструмент URL Inspection или Rich Results Test, чтобы посмотреть загруженные ресурсы, вывод консоли, исключения и отрисованный DOM. Используйте эти инструменты как вспомогательное доказательство и сверяйте их с актуальным тестом в анонимном браузере: клиентская аналитика не отражает полностью активность рендеринга Googlebot.
Не делайте динамический рендеринг архитектурным решением по умолчанию: Google называет его обходным путём, а не долгосрочным решением. Не занимайтесь клоакингом: контент для сканера должен оставаться равнозначным тому, что получает пользователь. Записывайте маршрут, состояние пользователя, сырой ответ, результат рендеринга и статус неудачно загруженных ресурсов, чтобы при обновлении фреймворка проверить изменения по тем же доказательствам.