AI-агентура
Разбор · 2026-07-02

Next.js SSR: 3 ошибки настройки, которые ломают SEO

Next.js на бумаге SEO-дружественный. На практике команды ловят одни и те же три ошибки — не потому что глупые, а потому что документация не выделяет эти пункты жирным. Разбор из аудита SaaS-платформы для DeFi-аналитики. Черный ящик, без доступа к коду. Что вижу извне и как это чинится.

Стек проекта: Next.js SSR, Cloudflare, интеграция с открытым API. Продукт в бете. Команда небольшая, документации по деплою я не видел. Всё что ниже — то что видно снаружи, из ответов сервера и HTML-заголовков.

1. Рассинхрон slug-маппинга: 404-контент под HTTP 200

Первое, что нашёл — критично: топ-5 самых крупных сущностей отрасли открывались как «Not found for slug: X». HTTP-статус страницы при этом — 200 OK.

Что это значит:

  • Пользователь заходит с гугла, видит красный алерт «данных нет», уходит. Bounce rate растёт.
  • Google получает 200 OK, индексирует страницу как рабочую. Через месяц замечает что содержимое «пустое», начинает деранжировать домен целиком.
  • Sitemap-парсер добавляет несуществующие протоколы в очередь на индексирование.

Причина, судя по симптомам, — slug в БД не совпадает с каноническим именем. Пример: сущность записана как «aave-v3», а посетитель пришёл по /protocol/aave. Роутинг находит запись «нет», рендерит error-компонент, но обёртка сохраняет HTTP 200.

Как чинить:

  • Слой алиасов: aave → aave-v3, uniswap → uniswap-v3 и т.д. Простая маппинг-таблица.
  • Когда сущности нет — вернуть 404 или 410 честно. В Next.js это notFound() из next/navigation.
  • 301-редирект на канонический slug при попадании на алиас.

2. Дублирующие meta robots на страницах ошибок

Открываю 404-страницу — в <head> два тега:

<meta name="robots" content="noindex">
<meta name="robots" content="index, follow">

Одновременно и «не индексируй», и «индексируй». Спецификация не описывает такую ситуацию — поведение поисковика зависит от реализации: обычно применяется более рестриктивное правило (noindex), но не гарантированно.

Причина — в Next.js App Router глобальный layout ставит один robots, а конкретный error-компонент добавляет второй. Оба остаются в DOM.

Как чинить:

  • Использовать metadata и generateMetadata в компоненте страницы. Next.js сам мёржит и не дублирует.
  • Проверить что глобальный layout не устанавливает robots силой через inline JSX.
  • Автотест на CI: HTML-парсер, считает количество <meta name="robots"> — если больше одного, падает билд.

3. Отсутствие security.txt и PWA-манифест с одной иконкой

Две мелочи, но обе видны каждому, кто проверяет:

Нет /.well-known/security.txt. Файл описан в RFC 9116 — стандарт того, как white-hat хакер должен сообщать об уязвимости. Для финансовой платформы (DeFi-аналитика) отсутствие security.txt читается как «мы не готовы к responsible disclosure». Bug bounty программы платформ (HackenProof, Immunefi) требуют этот файл при листинге.

Как чинить: положить public/.well-known/security.txt с содержимым:

Contact: mailto:security@yourdomain.com
Expires: 2027-01-01T00:00:00Z
Preferred-Languages: en
Canonical: https://yourdomain.com/.well-known/security.txt

PWA-манифест с одной иконкой 32×32. Файл manifest.json объявляет иконки для установки как PWA. Одна маленькая иконка — на Android при попытке «Добавить на главный экран» приложение получит размытый значок. На iOS вообще не установится.

Как чинить: добавить иконки 192×192, 512×512, apple-touch-icon 180×180. Работа на 15 минут через любой PWA-генератор (PWABuilder.com даёт весь пакет).

Что ещё стоит проверить в SSR-проекте перед продом

Не входило в разбор, но встречается регулярно:

  • sitemap.xml генерируется, но лежит устаревшим. Проверьте: он должен собираться при билде или на request-time из БД, а не быть статичным файлом.
  • Canonical на страницах пагинации. Аналогично WordPress-проблеме — каждая страница списка должна иметь canonical на саму себя.
  • Cache-Control для HTML. Cloudflare по умолчанию не кэширует HTML — нужно явно настроить или использовать stale-while-revalidate.
  • Метрики Core Web Vitals. Cloudflare Web Analytics или Real User Monitoring в самом Next.js. Без цифр — неясно что улучшать.
  • 404 без layout. Иногда 404-страница рендерится без глобальных footer/menu — пользователь не может вернуться на главную.

Как это встроить в процесс, чтобы не ловить снова

Все три ошибки — конфигурационные. Их можно отловить автоматически:

  • Pre-commit hook: Playwright пробегает по 5-10 ключевым URL, проверяет HTTP статус, количество meta robots, наличие Open Graph, наличие security.txt. Если ошибка — коммит блокируется.
  • CI после деплоя: Lighthouse CI с бюджетом по Core Web Vitals. Регрессия >10% — билд красный.
  • Alerting: периодический прогон по прод-URL, скрины в Slack при отклонениях. Работа на день, экономия — постоянно.

Свой Next.js-проект перед релизом?

Напишите в @ai_agentura — сделаю блиц-аудит с чек-листом. Асинхронно, без созвонов.