Тема
SEO — максимальная гибкость
Статус: проектирование объёма. Ключевое требование: SEO-подсистема даёт гибкость уровня Битрикс (умный фильтр, ЧПУ, региональность) + Yoast/RankMath (шаблоны, аудит). Хорошая новость: умный фильтр и мультигород уже реализованы в проектах студии
erиgulaev-dev— для ядра это перенос и обобщение, а не разработка с нуля.
Доноры (рабочий код студии)
| Донор | Что даёт | Путь |
|---|---|---|
er (RelaxMap) | Умный SEO-фильтр целиком: парсер пути → FilterState → канонизация → 301 → min_results-гейт → scope-шаблоны → блоки → перелинковка → тиринговый sitemap → orphan-прополка | er/project/src/app/Domain/Seo/ |
gulaev-dev | Шаблоны/переменные, полиморфная мета (IsSeoable), city-оверрайды, краулер-аудитор, LLM-генерация мета | gulaev-dev/src/app/Domains/Seo/ |
1. Мета-теги и шаблоны
- Шаблоны title/description/h1/h2 + og_title/og_description с переменными — на каждый тип страницы;
- приоритет резолва (3 уровня): ручной override страницы → шаблон типа → дефолт из модели; каждое поле независимо;
- полиморфное прикрепление (
IsSeoable/morphMany) — мета цепляется к любой сущности без изменения её таблицы; - OG + Twitter Card (наследование Twitter от OG), canonical (ручной > авто, всегда, в т.ч. self-referential), meta robots по правилам (index/noindex по типу/порогу/глубине);
- доп. robots-директивы (max-snippet, max-image-preview, noarchive), автообрезка по лимитам (title ~60, description 160), og:image по иерархии, мета per-локаль.
2. Переменные и подстановки
- Базовые:
{city},{category},{brand},{price},{price_from},{count},{year}; - падежи/склонения [РФ критично]: все 6 падежей города/категории/бренда (
{city_gen},{city_dat},{city_prep}, «в Москве»…), хранятся в JSONdeclensions, fallback lang→ru→именительный; - вычисляемые (агрегатные):
{count}(объектов на странице),{price_from}(мин. цена),{verified_count}— из БД в реальном времени, кешируются; - пользовательские: таблица
seo_variables— редактор задаёт свои ({company},{phone},{experience}); - региональные переменные: те же ключи с
city_id— город перекрывает глобальное (array_merge); - составные/контекстные:
{category_in_city},{price_coeff}(региональный коэффициент); - условные блоки (
{?district}в районе {district}{/district}— не выводить пустое), экранирование (htmlspecialchars для text, доверенный html без), тестер шаблона (Filament-превью), fallback-цепочка значений.
3. Умный фильтр / SEO-фильтр (ключевое)
Это Битрикс-«умный фильтр» в Laravel — проверено по рабочему коду er:
- генерация посадочных из комбинаций фильтров — каждая валидная комбинация (категория + гео + пресет + атрибуты) = отдельная индексируемая страница со своим URL, title, H1, текстом;
- парсинг фильтров из ЧПУ-пути (
SeoPathParser) — комбинация в URL, не в query; неизвестные сегменты → 404; - реестр slug'ов фильтров (
seo_filter_slugs) — маппинг сегмента URL на значение; - декларативные правила (
seo_filter_definitions) — значение фильтра → условие запроса без хардкода в контроллере; - индексируемые vs неиндексируемые: гейт
min_results(деф. 3) — thin-страница (мало объектов) не публикуется → 404; глубина комбинации ограничена; - автопрополка «сирот» (
seo:detect-orphans) — пересчёт объектов,is_indexable=falseпри падении ниже порога; - мета/блоки для фильтр-страниц по scope (city/category/preset/metro/district) с specificity+priority;
- каноникал для фильтр-выдач (
SeoCanonicalizer) — фиксированный порядок сегментов, иначе 301; каноникал пагинации/сортировки; - историческая карта slug (
deprecated_redirect_to) — переименовал сегмент → авто-301; - гео-уточнение (
metro/{station},district/{name}), пресеты (vip,cheap,verified,online).
4. URL и роутинг
- ЧПУ (slug вместо id, ID в публичных URL запрещён), правила slug (транслитерация кириллицы,
[a-z0-9-], составная уникальность); - переопределение/подмена URL — произвольный путь поверх авто-slug (аналог «символьного кода» Битрикс);
- канонизация (trailing slash, lowercase, схлопывание слэшей → 301), www/схема (на уровне Caddy +
URL::forceScheme); - мультиязычные URL (
/{lang}/...), региональные (подпапка/{city}/или поддоменcity.site.ru— выбор на проект), историческая карта URL (авто-301 при смене), fallback 404, роуты только черезroute('name').
5. Редиректы
Проверено по модели Redirect (gulaev-dev):
- 301/302 на запись, regex-правила (
is_regex:/old/(.*)→/new/$1), массовый импорт (CSV — миграция со старого сайта); - авто-редирект при смене URL (observer на slug — задел, довести в ядре);
- лог 404 → предложение редиректа (частые 404 → создать редирект в клик);
- счётчик срабатываний (
hits,last_hit_at— какие живые/мёртвые); - редиректы по локали/городу (
locale,city_id, null = для всех); - детект/устранение цепочек (A→B→C → A→C, циклы), редирект по гео/языку/устройству (осторожно: Google должен видеть контент).
6. Региональность (мультигород) [критично]
Проверено по er (ResolveUserCity) и gulaev-dev (CityResolver, city_overrides):
- определение города (цепочка): сегмент URL/route-param → cookie → geo-IP → город по умолчанию; кеш резолва; вариант по поддомену;
- иерархия регион → город (
Region+City, наследование данных); - полевое переопределение по городу (
city_overrides: overridable + city_id + locale- data_json) — любое поле любой сущности под город, наследование = базовое значение при отсутствии override;
- региональные цены (коэффициент или прямой override), телефоны/адреса/контакты, мета/тексты/блоки (city-scope перекрывает глобальное), склонения города во всех текстах;
- hreflang для языков (+ x-default; для город-версий одного языка hreflang НЕ применяется — это дубли, решаются canonical);
- поддомены vs подпапки (выбор на проект), дописывание city-префикса внутренним ссылкам, гео-таргет в Яндекс.Вебмастере, bulk-применение оверрайдов (без N+1).
7. Микроразметка (Schema.org / JSON-LD)
- Типы: Organization/LocalBusiness, Product, Article, Service, FAQPage, BreadcrumbList, Review/AggregateRating, Event, WebSite+SearchAction, Offer;
- JSON-LD из данных моделей (не хардкод, обновляется автоматически);
schema_typeна шаблоне типа; - LocalBusiness с гео (address, geo, telephone, openingHours — на город), FAQ из SEO-блоков формата
faq→ FAQPage автоматически, BreadcrumbList из навигации, Product с Offer/Review; - авто + ручное переопределение JSON-LD, валидация разметки в аудите, Sitelinks SearchBox.
8. Техническое SEO
Проверено: тиринг sitemap (er), gzip-чанкинг (gulaev-dev):
- sitemap индексный + по типам/городам, gzip, авто-разбивка при >50 000 URL, тиринг приоритетов (город 0.9 / категория 0.8 / комбинация 0.5) + changefreq + lastmod, min_results в sitemap (thin не попадают), ленивая генерация (LazyCollection — миллионы URL без OOM), HTML-sitemap;
- robots.txt (Disallow admin/api/cart, Allow статики, строка Sitemap, per-раздел);
- пагинация (rel-next/prev, каноникал), дубли-детект (хеши title/description), orphan-детект (страницы без входящих ссылок), битые ссылки, глубина вложенности, Core Web Vitals (флаг slow_response, хук под PageSpeed), noindex/canonical mismatch детект, warm-cache/rebuild, ping поисковиков / IndexNow.
9. Аналитика и аудит
Проверено: полный краулер + issue-detector (gulaev-dev):
- SEO-аудит страниц (18+ проверок: missing/short/long/duplicate title&description, H1, OG, noindex, canonical mismatch, slow response) → балл 0–100;
- встроенный краулер (
seo:crawl: db/sitemap/spider/commercial, visited-set в Redis, обход внутренних ссылок, прогресс); - анализ контента (word_count, h2, img без alt, ссылки, schema), классификация страниц (коммерческие — приоритет), отчёт покрытия (шаблоны, блоки, города), топ дублей;
- интеграции: Яндекс.Вебмастер (индексация, позиции, переобход, региональность), Search Console, IndexNow, отслеживание позиций и индексации;
- LLM-генерация мета/контента (
llm:generate-seo— Claude API генерит title/desc и HTML-блоки в статусе draft→активация), не-LLM генерация (seo:generate-metaиз шаблонов+переменных).
10. Контентное SEO
- авто-перелинковка («Похожие страницы» по гео+категориям,
SeoLinksBuilder), авто-линковка по ключам (замена вхождений на ссылку, лимит на страницу), анкор-лист (реестр ключ→URL, контроль переспама); - related-контент, хлебные крошки (+ BreadcrumbList), ЧПУ для тегов/категорий (
TagSeo), SEO-блоки по позициям (top/bottom/sidebar, форматы html/faq/text); - анализ плотности ключей, читаемость (аналог Yoast readability), контроль alt, фокус-ключевое слово + чеклист, черновик→ревью контента.
Что перенести, а что реализовать заново
| Уже в донорах (перенос) | Только задел (реализовать в ядре) |
|---|---|
Умный фильтр целиком (er) | Авто-редирект при смене slug (observer) |
Мультигород + city-оверрайды (gulaev-dev) | Лог 404 → редирект, детект цепочек |
Полиморфная мета IsSeoable | hreflang (довести до рантайма) |
| Тиринговый ленивый sitemap | Авто-линковка по ключам, анкор-лист |
| Краулер-аудитор (18+ проверок) | Плотность ключей, читаемость |
| Склонения (6 падежей) | Интеграции Вебмастер/Search Console/IndexNow |
| LLM-генерация мета | Транслитерация в рантайме (в er slug пред-сохранены) |
Обязательные примитивы SEO-модуля ядра
- Полиморфное прикрепление мета к любой сущности (
IsSeoable). - Движок переменных с падежами и экранированием.
- Scope-матчер шаблонов (базовый page_type + опциональный scope для фильтр-страниц).
- Канонизатор с 301 (фиксированный порядок сегментов).
- min_results-гейт индексируемости + orphan-крон.
- Тиринговый ленивый sitemap.
- Краулер-аудитор.
- Полиморфные city-оверрайды с наследованием регион→город.
Модель шаблонов: комбинировать два подхода доноров — простой
page_type+city_idматчинг (gulaev-dev) для типовых страниц + гибкийscope-JSON матчинг (er) для фильтр-страниц. Это даёт и простоту, и мощь умного фильтра.
Связь: SEO-база — в ядре; расширенный SEO-движок (умный фильтр, аудит, auto-linking) — функц-модуль. Мультигород — отдельный модуль, плотно связанный с SEO.