https://github.com/2naive/seo-audit
Claude Skill
https://github.com/2naive/seo-audit
Last synced: 30 days ago
JSON representation
Claude Skill
- Host: GitHub
- URL: https://github.com/2naive/seo-audit
- Owner: 2naive
- Created: 2026-04-10T23:38:50.000Z (4 months ago)
- Default Branch: master
- Last Pushed: 2026-04-10T23:44:45.000Z (4 months ago)
- Last Synced: 2026-04-11T01:21:43.471Z (4 months ago)
- Language: JavaScript
- Size: 630 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# SEO Audit Skill
**Версия:** см. `generate-report.js` константа `SKILL_VERSION`
**Автор:** SEO Audit от Nedzelsky.pro
**Расположение:** `.claude/skills/seo-audit/`
Скилл для Claude Code (`/seo-audit [URL]`) — выполняет полный технический SEO-аудит сайта и генерирует отчёт в форматах Markdown, HTML и PDF.
---
## Файлы
| Файл | Назначение |
|------|-----------|
| `SKILL.md` | Основная инструкция для агента (все фазы аудита) |
| `generate-report.js` | Генератор HTML+PDF из `report-data.json` |
| `CHANGELOG.md` | История изменений с обоснованием |
| `README.md` | Этот файл — документация и архитектура |
Выходные файлы создаются в `{корень-проекта}/seo-audit-output/` и **не хранятся в репозитории** (`.gitignore`).
---
## Использование
```bash
/seo-audit https://example.com
```
Агент создаёт в `seo-audit-output/`:
- `seo-report-{domain}-{datetime}.md` — Markdown
- `seo-report-{domain}-{datetime}.html` — HTML (открыть в браузере)
- `seo-report-{domain}-{datetime}.pdf` — PDF
- `report-data-{domain}-{datetime}.json` — исходные данные
- `desktop-{domain}-{datetime}.png` — скриншот десктоп
- `mobile-{domain}-{datetime}.png` — скриншот мобильный
---
## Архитектура
### Режимы работы
| Режим | Условие | Что пропускается |
|-------|---------|-----------------|
| **Полный (Chrome)** | `mcp__claude-in-chrome__navigate` доступен | — |
| **Базовый** | Chrome недоступен, пользователь подтвердил | Фаза 2 целиком (JS-анализ, скриншоты, Lighthouse) |
### Фазы аудита
```
Фаза 0 → Проверка Chrome-подключения
Фаза 1 → Статичные проверки (WebFetch + Bash curl)
Фаза 2 → Браузерный анализ (Chrome MCP-инструменты)
Фаза 3 → Сборка report-data.json
Фаза 4 → generate-report.js → HTML + PDF
```
**Фаза 0** — пытается открыть URL через `mcp__claude-in-chrome__tabs_create_mcp` + `navigate`. Если инструменты недоступны — запрашивает подтверждение на базовый режим.
**Фаза 1** — только WebFetch и Bash (curl). Не требует Chrome. Проверяет:
- robots.txt (блокировки, Sitemap:, Host:)
- sitemap.xml (формат, количество URL, lastmod)
- www/http редиректы (зеркала)
- 404-страницу
- raw HTML главной (мета-теги, OG, Schema.org, E-E-A-T ссылки, H1-H6)
- HTTP-заголовки (HSTS, X-Frame-Options, gzip, Cache-Control, TTFB)
- 2–3 страницы из sitemap
- Дубли title/description между страницами
- Session ID в URL, пагинация, HTML-карта, «О компании», политика
**Фаза 2** — требует Chrome. Проверяет:
- JS-рендеренный контент (сравнение с raw HTML → JS-зависимость)
- Скриншоты desktop (1280×900) и mobile (390×844)
- JS-ошибки в консоли
- Качество анкоров внутренних ссылок
- Скрытый контент (display:none, visibility:hidden, font-size<5px)
- Schema.org через браузер
- Lighthouse (Performance, SEO, Accessibility, Best Practices + 6 метрик)
**Фаза 3** — агент собирает все данные в `report-data-{domain}-{datetime}.json`. Схема описана ниже.
**Фаза 4** — запускает `generate-report.js`, который читает JSON и генерирует HTML + PDF через Chrome headless `--print-to-pdf`.
---
## Схема report-data.json
```json
{
"url": "https://example.com",
"date": "YYYY-MM-DD HH:MM",
"mode": "full | basic",
"skillVersion": "1.3.2",
"summary": {
"summary": "Текст резюме",
"pagesAnalyzed": 4,
"critical": 7,
"warnings": 11,
"ok": 19
},
"scores": {
"Мета-теги": 6,
"Структура контента": 7,
...
},
"scoreDetails": {
"Мета-теги": ["✅ title 52 симв.", "🔴 description 285 симв."],
...
},
"recommendations": [
{
"title": "...",
"description": "...",
"priority": "high | medium | low",
"difficulty": "low | medium | high",
"fix": "nginx.conf: gzip on;"
}
],
"pages": [
{
"url": "...",
"issues": [{ "severity": "critical|warning|info|ok", "msg": "..." }]
}
],
"scoreDetails": { ... },
"lighthouse": {
"available": true,
"performance": 84,
"seo": 100,
"accessibility": 98,
"bestPractices": 77,
"metrics": { "FCP": "1.2 s", "LCP": "2.4 s", ... }
},
"screenshotPaths": {
"desktop": "/abs/path/desktop-example.com-2026-04-07-1457.png",
"mobile": "/abs/path/mobile-example.com-2026-04-07-1457.png"
},
"technical": [
{ "check": "HTTPS", "status": "ok|warning|critical|info", "value": "..." },
...
]
}
```
### Правила заполнения
- `scoreDetails` — **обязателен** для каждой категории из `scores`. Каждый элемент — факт с иконкой: `"✅ title 52 симв."`, `"🔴 description 285 симв. (норма 70-160)"`. Пустые массивы недопустимы.
- `screenshotPaths` — абсолютные пути к реально существующим PNG-файлам или `null`.
- `skillVersion` — текущая версия скилла (из константы `SKILL_VERSION` в `generate-report.js`).
- `lighthouse.available: false` — если Lighthouse не запустился; остальные поля опциональны.
---
## generate-report.js
Node.js скрипт без внешних зависимостей (только стандартная библиотека).
```
node generate-report.js [output-dir]
```
### Что генерирует
1. **HTML** — полностью самодостаточный файл (inline CSS, base64 изображения). Открывается в любом браузере.
2. **PDF** — через Chrome headless `--print-to-pdf`. Требует Chrome в одном из стандартных путей.
### Секции отчёта (по порядку)
| # | Секция | Источник данных |
|---|--------|----------------|
| 1 | Шапка (URL, дата, режим, общая оценка) | `url`, `date`, `mode`, `scores` |
| 2 | Статистика (4 плитки) | `summary` |
| 3 | Оценки по категориям + детали | `scores`, `scoreDetails` |
| 4 | Lighthouse | `lighthouse` |
| 5 | Рекомендации (сгруппированы по приоритету) | `recommendations` |
| 6 | Проблемы по страницам | `pages` |
| 7 | Технические проверки | `technical` |
| 8 | Скриншоты (embedded base64) | `screenshotPaths` |
| 9 | Топ-5 действий с максимальным ROI | `recommendations` (фильтрация) |
| — | Подвал с версией | `SKILL_VERSION`, `url`, `date` |
### Цветовая схема оценок
| Значение | Цвет | Смысл |
|----------|------|-------|
| 8–10 | Зелёный `#22c55e` | Хорошо |
| 5–7 | Жёлтый `#f59e0b` | Требует внимания |
| 1–4 | Красный `#ef4444` | Критично |
---
## Известные ограничения
| Ограничение | Обходной путь |
|------------|---------------|
| Скриншоты показывают не тот сайт | Перед скриншотом проверить активную вкладку через `tabs_context_mcp` |
| Lighthouse не запускается | `npm install -g lighthouse` вручную |
| Chrome не найден для PDF | Установить Chrome по стандартному пути |
| Большие base64 скриншоты не помещаются в Bash echo | Использовать временный файл: `node -e "fs.writeFileSync(...)"` |
---
## Требования
| Компонент | Версия | Обязательность |
|-----------|--------|---------------|
| Node.js | ≥ 16 | Обязательно (generate-report.js) |
| Google Chrome | любая | Обязательно (PDF генерация, Chrome-режим) |
| lighthouse | ≥ 10 | Опционально (устанавливается автоматически) |
| Claude Code | ≥ 1.0.36 | Обязательно |
| Claude in Chrome extension | ≥ 1.0.36 | Для полного режима |
---
## Хронология ключевых решений
### Почему Chrome MCP, а не Puppeteer/Playwright?
Claude Code уже интегрирован с Chrome через расширение. Использование `mcp__claude-in-chrome__*` инструментов не требует дополнительных зависимостей и работает в рамках той же сессии.
### Почему PDF через Chrome --print-to-pdf, а не wkhtmltopdf/puppeteer?
Chrome уже требуется для аудита, добавление второй зависимости избыточно. Chrome headless корректно рендерит CSS (градиенты, print-color-adjust, @page counters).
### Почему inline CSS в HTML, а не внешние файлы?
Самодостаточный HTML-файл можно открыть без сервера и отправить клиенту одним файлом. PDF генерируется из этого же файла — нет расхождений.
### Почему скриншоты встраиваются как base64, а не ссылки на файлы?
PDF должен содержать изображения без внешних зависимостей. При пересылке PDF клиенту скриншоты сохраняются.
### Почему report-data.json с timestamp в имени?
Предыдущая версия перезаписывала единственный файл `report-data.json` при каждом запуске. Теперь каждый аудит хранит свои данные отдельно — можно повторно сгенерировать отчёт из старых данных.
### Почему scoreDetails обязателен?
Без него оценка "Мобильность: 7/10" — субъективное мнение агента без обоснования. Клиент не понимает, что именно проверялось. scoreDetails превращает цифру в верифицируемые факты.