Skip to content

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}, «в Москве»…), хранятся в JSON declensions, 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 → редирект, детект цепочек
Полиморфная мета IsSeoablehreflang (довести до рантайма)
Тиринговый ленивый sitemapАвто-линковка по ключам, анкор-лист
Краулер-аудитор (18+ проверок)Плотность ключей, читаемость
Склонения (6 падежей)Интеграции Вебмастер/Search Console/IndexNow
LLM-генерация метаТранслитерация в рантайме (в er slug пред-сохранены)

Обязательные примитивы SEO-модуля ядра

  1. Полиморфное прикрепление мета к любой сущности (IsSeoable).
  2. Движок переменных с падежами и экранированием.
  3. Scope-матчер шаблонов (базовый page_type + опциональный scope для фильтр-страниц).
  4. Канонизатор с 301 (фиксированный порядок сегментов).
  5. min_results-гейт индексируемости + orphan-крон.
  6. Тиринговый ленивый sitemap.
  7. Краулер-аудитор.
  8. Полиморфные city-оверрайды с наследованием регион→город.

Модель шаблонов: комбинировать два подхода доноров — простой page_type+city_id матчинг (gulaev-dev) для типовых страниц + гибкий scope-JSON матчинг (er) для фильтр-страниц. Это даёт и простоту, и мощь умного фильтра.

Связь: SEO-база — в ядре; расширенный SEO-движок (умный фильтр, аудит, auto-linking) — функц-модуль. Мультигород — отдельный модуль, плотно связанный с SEO.

Внутренняя база знаний студии