Nuxt-модуль
sitemap.xml, robots.txt и типизированный JSON-LD из коробки. Ставится одной командой, конфиг не обязателен.
useJsonLduseRanklintIgnoreNuxt-модуль, таб в DevTools и краулер для CI, который роняет пайплайн на SEO-регрессиях. Любой стек.
24 страницы · playwright chromium · 7.1s
Ranklint читает тот HTML, который реально отдаётся роботу, и называет конкретную проблему: пустой title, битый canonical, сломанную иерархию заголовков, односторонний hreflang. Три поверхности — один набор правил.
sitemap.xml, robots.txt и типизированный JSON-LD из коробки. Ставится одной командой, конфиг не обязателен.
useJsonLduseRanklintIgnoreПроблемы, структура заголовков и мета-теги текущего маршрута — прямо на дев-сервере, пока ты пишешь код.
live-проверкасветлая и тёмнаяОбходит задеплоенный сайт через Chromium. Работает с любым стеком — Nuxt не нужен.
auditdiffwatchТе же правила, запущенные прямо в этой вкладке. Вставь разметку страницы — линтер ответит здесь же, без сервера и без установки.
<!doctype html> <html lang="en"> <head> <title>Pricing</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta property="og:title" content="Pricing"> <meta property="og:description" content="Plans and prices for teams of every size."> <meta property="og:image" content="https://example.com/og/pricing.png"> </head> <body> <h1>Pricing plans for growing teams</h1> <h3>What the team plan includes</h3> <img src="/plans.png"> <h1>Frequently asked questions</h1> </body> </html>
Таб SEO в Nuxt DevTools показывает текущий маршрут так, как его увидит робот: список проблем, дерево заголовков и все мета-теги. Панель обновляется при навигации на странице и при изменениях DOM, плюс есть кнопка Rescan.
У каждого правила есть id и уровень: error, warn, info/off. Уровни лежат в конфиге рядом с кодом, а не в чьей-то голове.
export default defineRanklintConfig({
rules: {
'canonical:required': 'error',
'http:ttfb-budget': ['warn', { p75: 600 }],
'images:no-lazy-above-fold': 'off',
},
})Квартальный краул превращается в бэклог, о котором все забывают. Ranklint проверяет каждый пул-реквест: audit собирает JSON-отчёт, diff сравнивает его с базовой веткой и роняет пайплайн только на новых ошибках. Старые долги не мешают мержить.
| уровень | правило | URL | что случилось |
|---|---|---|---|
| error | meta:title-required | /bugs/title-missing | Page has no <title> |
| error | meta:description-required | /bugs/description-missing | Page has no meta description |
| error | headings:single-h1 | /bugs/h1-multiple | Page has 2 <h1> elements, expected exactly 1 |
| warn | images:alt-required | /bugs/images-bad | Image has no alt attribute |
| warn | images:dimensions-required | /bugs/images-bad | Image has no explicit width/height |
| warn | images:no-lazy-above-fold | /bugs/images-bad | Image in the viewport uses loading="lazy" |
markdownjsonjunithtmlgitlabgithubjunit кладётся в отчёты раннера, gitlab — это отчёт Code Quality, а github превращает каждое замечание в аннотацию в пул-реквесте.
$ ranklint audit --url https://preview --reporter json --output report.json
$ ranklint diff --base main --current report.json --reporter markdownРевью не ловит SEO-регресс: в браузере всё выглядит целым. Код возврата ловит.
У каждой зоны свой список проверок и свой владелец: свою зону краулер обходит целиком, чужую — только HEAD-проверкой ссылок, которые в неё ведут.
Краулер ходит по HTTP и рендерит страницы в Chromium через Playwright. Ему всё равно, что отдаёт сервер — Next, Django, WordPress или статика на CDN.
Прогон ranklint audit --url https://prod --mode monitor по расписанию обходит прод, складывает отчёты в историю и пишет, когда что-то сломалось.
LCP, CLS и INP реальных пользователей по всему origin попадают в тот же отчёт, рядом с замечаниями линтера.
LCPCLSINPURL Inspection отдаёт вердикт индексации, coverageState и проблемы расширенных сниппетов для первых десяти страниц краула.
Сообщение в Slack или Telegram при новом error, история отчётов и дашборд — на GitHub или GitLab Pages.
Один шаг после мониторинга, и каждый плановый прогон выкладывает статический сайт на GitHub или GitLab Pages. Команда видит ошибки по страницам, тренды и историю без терминала.

$ ranklint dashboard \
--dir .ranklint/reports --out public--logo--brand-name--accent--run-urlСвой логотип, название и акцентный цвет вместо наших. --run-url добавляет кнопку Run audit, которая открывает пайплайн в CI.
Как настроить дашбордSEO-линтер читает HTML, который сайт реально отдаёт, и показывает то, что стоит трафика: пропавший title, canonical, ведущий на редирект, заголовок, который прыгает с h1 на h3, одностороннюю пару hreflang. Идея та же, что у ESLint, только применённая к разметке, которую читают поисковики, а не к JavaScript, который уезжает в прод. На выходе не оценка от 0 до 100, а список конкретных проблем: правило, адрес страницы, селектор и подсказка, что с этим делать.
Обычно SEO-работа умирает в таблице. Краулер запускают раз в квартал, выгружают список из 400 проблем, и список гниёт, пока сайт продолжает выкатываться. Линтер переворачивает порядок: краул идёт на каждом пул-реквесте, отчёт превращается в diff, и смотреть нужно только на то, что изменилось с последней зелёной сборки. ranklint сохраняет JSON-отчёт как артефакт сборки, сравнивает с ним текущий прогон и публикует разницу комментарием. Набор правил и их severity лежат в репозитории рядом с кодом, поэтому изменение требований к SEO проходит то же ревью, что и любой другой коммит.
Как связаны audit и diffSEO-регрессии редко выглядят драматично. Рефакторинг убирает canonical из одного шаблона, миграция CMS оставляет 40 страниц без описания, эксперимент добавляет noindex, и его забывают снять. Такие правки проходят код-ревью, потому что в браузере ничего не сломано. Краул, который идёт вместе с тестами, ловит их в тот же час. Severity задаётся на каждое правило, поэтому длина title может остаться предупреждением, пока пропавший canonical останавливает мердж.
Настройка правил и severityРешение принимает код возврата, а не человек.
В приложении на Nuxt 4 модуль закрывает всё, что относится к рутине. Он отдаёт sitemap.xml из маршрутов приложения, robots.txt, который различает стейджинг и прод, и JSON-LD с валидацией по Schema.org прямо во время разработки, так что сломанный блок Product или FAQPage виден как предупреждение в консоли, а не как тихая потеря расширенных сниппетов. Каждый блок отключается, а отключённый блок не регистрируется и ничего не стоит в рантайме. Композаблы подключаются только там, где они нужны: useJsonLd для структурированных данных страницы, useRanklintIgnore для точечного отключения правил.
Обзор модуляКраулер говорит по HTTP и ничего не знает про внутренности фреймворка. Достаточно указать URL: каждая страница рендерится в Chromium, поэтому клиентский контент оценивается так же, как его оценивает поисковик, а страницы, которые существуют только после гидрации, попадают в отчёт как проблема индексации. Один домен делится на зоны, когда под разными путями живут разные приложения, а профили держат медленные проверки в стороне от быстрого пайплайна. Отчёт выгружается в markdown, json, junit, html или комментарий в GitLab и GitHub, поэтому результат читается там, где команда уже работает.
Начать с CLIranklint diff — он роняет сборку только на новых ошибках относительно базовой ветки, тогда как голый audit выходит с кодом 1 на любой error. Запускай diff в пайплайне, и накопленный долг остаётся в отчёте.useRanklintIgnore внутри страницы. Больше нигде точечного переопределения нет: поставь правилу off в rules или убери адрес из краула через crawl.ignore.Поставь модуль, добавь два шага в пайплайн — и дальше решает код возврата.