Если вы занимаетесь SEO для сайтов на React или Vue, рано или поздно упрётесь в одну и ту же проблему: Яндекс плохо индексирует контент, который рендерится на клиентской стороне. Решение, которое рекомендуют все SEO-специалисты — серверный рендеринг (SSR). В этой статье разбираемся, что такое SSR, как он работает и как его правильно настроить для достижения максимального SEO-эффекта.
Что такое серверный рендеринг и почему это важно для SEO
Клиентский рендеринг (CSR) — браузер получает пустой HTML и JS-файлы. Выполняет JavaScript, строит DOM, показывает пользователю готовую страницу. Поисковый робот при этом видит пустой HTML и должен сам выполнять JS — что Яндекс делает с задержкой и не всегда корректно.
Серверный рендеринг (SSR) — сервер получает запрос, выполняет JavaScript, генерирует полноценный HTML и отдаёт его клиенту. Поисковый робот получает готовый HTML с контентом, мета-тегами и ссылками — так же, как с обычного PHP или Python сайта.
Преимущества SSR для SEO очевидны:
- Робот сразу видит весь контент без дополнительного рендеринга.
- Мета-теги (title, description, canonical) присутствуют в исходном HTML.
- Внутренние ссылки читаются корректно.
- Время до первого байта (TTFB) и LCP обычно лучше, чем у CSR.
Next.js: SSR для React-проектов
Next.js — де-факто стандарт для React-проектов с SSR. Разработан Vercel, активно поддерживается, имеет огромную экосистему.
Режимы рендеринга в Next.js
Next.js предлагает несколько режимов на выбор для каждой страницы:
SSR (getServerSideProps) — страница рендерится на сервере при каждом запросе.
export async function getServerSideProps(context) {
const { params } = context;
const data = await fetchData(params.slug);
return { props: { data } };
}
Подходит для: страниц с часто меняющимися данными (новости, цены, остатки товаров).
SSG (getStaticProps) — страница генерируется один раз при сборке.
export async function getStaticProps() {
const posts = await getAllPosts();
return { props: { posts } };
}
Подходит для: блогов, лендингов, документации — там, где контент меняется редко.
ISR (Incremental Static Regeneration) — статическая страница, которая перегенерируется в фоне через заданный интервал.
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 3600, // обновлять каждый час
};
}
Подходит для: большинства коммерческих проектов — баланс между производительностью и актуальностью данных.
SEO-настройки в Next.js
Компонент Head:
import Head from 'next/head';
export default function ProductPage({ product }) {
return (
<>
<Head>
<title>{product.title} — купить в Москве</title>
<meta name="description" content={product.description} />
<link rel="canonical" href={`https://example.com/product/${product.slug}`} />
</Head>
{/* остальной контент */}
</>
);
}
Библиотека next-seo даёт больше возможностей и упрощает работу с Open Graph, Twitter Cards, JSON-LD:
import { NextSeo } from 'next-seo';
<NextSeo
title="Заголовок страницы"
description="Описание страницы"
canonical="https://example.com/page"
openGraph={{
title: 'OG заголовок',
description: 'OG описание',
}}
/>
Sitemap в Next.js
Используйте пакет next-sitemap:
// next-sitemap.config.js
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
exclude: ['/admin/*', '/account/*'],
};
Добавьте в package.json:
"postbuild": "next-sitemap"
Nuxt.js: SSR для Vue-проектов
Nuxt.js — аналог Next.js для Vue. Точно так же предоставляет SSR «из коробки» с минимальной настройкой.
Режимы рендеринга в Nuxt 3
В Nuxt 3 рендеринг настраивается в nuxt.config.ts:
export default defineNuxtConfig({
ssr: true, // включить SSR (по умолчанию true)
})
Для отдельных страниц можно переключать режим:
<script setup>
definePageMeta({
ssr: false // эта страница будет рендериться на клиенте
})
</script>
useFetch и useAsyncData — основные инструменты для получения данных на сервере:
<script setup>
const { data: product } = await useFetch(`/api/products/${route.params.slug}`);
</script>
SEO в Nuxt 3
Nuxt 3 имеет встроенные composables для управления мета-тегами:
<script setup>
useSeoMeta({
title: product.value.title,
description: product.value.description,
ogTitle: product.value.title,
ogDescription: product.value.description,
robots: 'index, follow',
})
useHead({
link: [{ rel: 'canonical', href: `https://example.com/${route.path}` }]
})
</script>
Sitemap в Nuxt 3
Используйте модуль @nuxtjs/sitemap:
npx nuxi module add @nuxtjs/sitemap
export default defineNuxtConfig({
sitemap: {
hostname: 'https://example.com',
exclude: ['/admin/**'],
}
})
SSR vs SSG vs ISR: что выбрать для разных задач
| Тип страницы | Рекомендуемый режим | Причина |
|---|---|---|
| Карточка товара (меняющаяся цена) | SSR | Данные должны быть актуальны |
| Категория товаров | ISR (revalidate: 1800) | Меняется нечасто, кэш ускоряет |
| Статья блога | SSG | Меняется редко, максимальная скорость |
| Главная страница | ISR | Баланс актуальности и скорости |
| Личный кабинет | CSR (без SSR) | Не нужно индексировать |
Частые ошибки при настройке SSR для SEO
Ошибка 1: SSR включён, но canonical не настроен
Даже при SSR canonical нужно прописывать для каждой страницы. Без canonical Яндекс может проиндексировать дублирующиеся URL (с www и без, с / и без, с GET-параметрами).
Ошибка 2: Robots.txt закрывает JS и CSS
Некоторые разработчики по привычке запрещают в robots.txt доступ к статическим ресурсам. При SSR это не так критично, но всё равно плохая практика — Яндекс должен видеть все ресурсы.
Ошибка 3: Разные данные на сервере и клиенте (hydration mismatch)
Если данные на сервере и клиенте различаются, React или Vue выдают предупреждение о «hydration mismatch». Это не только UX-проблема — это означает, что контент, отданный роботу, может отличаться от того, что видит пользователь.
Ошибка 4: TTFB слишком высокий
SSR добавляет нагрузку на сервер — время до первого байта растёт. Если TTFB превышает 800мс, это негативно влияет на Core Web Vitals и потенциально на ранжирование.
Решения:
- Кэширование на уровне Redis или Varnish.
- Переход на ISR или SSG там, где это возможно.
- Оптимизация запросов к базе данных.
- CDN с edge-функциями (Cloudflare Workers, Vercel Edge).
Проверка SSR в Яндекс.Вебмастере
После настройки SSR обязательно проверьте:
- Проверка статуса URL — убедитесь, что в «исходном HTML» уже есть контент.
- Отчёт по индексированию — количество страниц в индексе должно вырасти.
- Диагностика — нет ли ошибок с конкретными страницами.
Инструменты вроде ClickFlow позволяют автоматически отслеживать изменения в индексировании после внедрения SSR: насколько вырос охват страниц, улучшились ли позиции по ключевым запросам, нет ли регрессий. Это особенно ценно при миграции крупного проекта с CSR на SSR.
Angular Universal: SSR для Angular
Если ваш проект на Angular, используйте Angular Universal — официальное решение для SSR:
ng add @nguniversal/express-engine
После настройки Angular Universal рендерит страницы на сервере через Express.js. Настройка мета-тегов через Meta сервис Angular:
import { Meta, Title } from '@angular/platform-browser';
constructor(private meta: Meta, private title: Title) {
this.title.setTitle('Заголовок страницы');
this.meta.updateTag({ name: 'description', content: 'Описание страницы' });
}
Итог: план перехода на SSR
- Аудит текущего состояния — проверьте в Вебмастере, сколько страниц проиндексировано и как выглядит их кэш.
- Выбор фреймворка — Next.js для React, Nuxt.js для Vue, Angular Universal для Angular.
- Приоритизация страниц — начните с наиболее важных для SEO (карточки, категории, статьи).
- Настройка мета-тегов — для каждого типа страницы настройте динамические title, description, canonical.
- Sitemap — обновите или создайте sitemap, отправьте в Вебмастер.
- Мониторинг — настройте отслеживание индексирования и позиций после внедрения.
- Оптимизация производительности — следите за TTFB и Core Web Vitals.
SSR — это инвестиция, которая окупается ростом органического трафика. Проекты, перешедшие с CSR на SSR, как правило, видят значительный рост индексируемых страниц и улучшение позиций в Яндексе в течение 2–3 месяцев после внедрения.