Перейти к содержимому
← Назад к блогу

Фабрика лендингов: 20 шаблонов, 200 страниц, один рендер

В феврале 2025 клиент попросил 200 лендингов на 40 городов и пять услуг. Он прислал таблицу с городом, услугой, ценой и телефоном. Хотел, чтобы каждая страница выглядела локальной и ранжировалась. Я оценил две недели за систему, а не за страницы. Он спросил, откуда возьмутся страницы. Я показал, как строка CSV становится живым URL за 90 секунд. Он одобрил фабрику.

Скриншот лога импорта CSV 2025-02-18 14:32: 200 строк импортировано, 200 страниц сгенерировано, sitemap.xml пересобран на 200 url, сборка 94 секунды.

Три таблицы, что держат фабрику

Я держу фабрику в трёх таблицах, а не в файлах. Файлы ломаются, когда счёт растёт.

  • landing_templates хранит 15–20 шаблонов. Каждый шаблон называет блоки по порядку: hero, features, pricing, testimonials, faq, cta и опционально gallery или map. Порядок блоков храню как JSON, а не кодом.
  • content_blocks хранит 5–10 вариантов на блок. Вариант hero для логистики показывает ночной док. Вариант для клиник показывает холл. Каждый вариант несёт слоты текста: заголовок, подзаголовок и текст CTA.
  • landing_pages хранит строку на живую страницу с городом, услугой, id шаблона, id вариантов блоков и SEO-полями. Таблица ab_test_variants держит строку на тест с долей 50/50 и флагом победителя.

Один рендер читает таблицы и пишет HTML. Я зову его LandingRenderer. Он берёт строку landing_pages, грузит шаблон и варианты блоков, заполняет слоты из строки и пишет страницу. Тот же рендер пишет sitemap и RSS. Без второй системы.

Как страница собирается из строки

Клиент грузит CSV с колонками town, service, price, phone, hero image. Сервер проверяет таблицу, вставляет строки в landing_pages и берёт шаблон по услуге и вариант блока по городу. Цена и телефон заполняют слоты. Картинка геро идёт в галерею, когда есть. Задача зовёт LandingRenderer на каждую новую строку и пишет файлы в /l/[town]/[service]. Карта сайта пересобирается после последней записи. 200 страниц выходят без деплоя. Пайплайн за этими записями я тоже сократил: с 8 минут до 90 секунд на деплой, шаги разбираю в посте Как я сократил деплой с 8 минут до 90 секунд.

  • Массовый импорт тянет 200 строк меньше чем за две минуты на инстансе 512 МБ.
  • Детект дублей блочит тройку город+услуга+шаблон. Вторая загрузка обновляет, не дублирует.
  • A/B-варианты делят строку с суффиксом /a и /b. Деление трафика на edge через cookie и 302, а не дубли URL.
  • SEO чист: одна страница — один title, один description, один canonical, один hreflang когда нужно.

Почему шаблоны бьют страницы

Смена блока шаблона обновляет все страницы, что его используют. Я сменил копию блока FAQ раз и 84 страницы обновились одним запросом. Если бы менял страницы, правил бы 84 файла. Шаблоны дают одно место улучшения. Варианты дают много лиц.

Я держу 15–20 шаблонов, потому что пять услуг на четыре типа городов покрывают большинство без тесноты выбора. Держу 5–10 вариантов блока, потому что десять геро-вариантов на десять pricing-вариантов уже дают сотню комбо. Больше вариантов растёт выбор без роста конверсии. Каждый выживший вариант я всё равно читаю по фиксированному списку точек, и он лежит в посте Шаблон CRO-аудита: 12 точек, которые двигают выручку.

Что меряю

Каждая страница пишет визиты, отправки форм и id вариантов, что рендерились. Через десять дней сравниваю hero-варианты внутри одного шаблона и гашу два нижних. Через тридцать сравниваю шаблоны внутри услуги и ставлю на паузу нижний шаблон. Фабрика учится, пока ты продаёшь. Чтобы учиться, нужна аналитика, связанная с деньгами: конвейер разбираю в посте CRO как конвейер: от аналитики до выручки.

Как скопировать фабрику в малом

Собери три таблицы, затем рендер. Засей три шаблона и два варианта на блок. Импортируй десять строк из CSV. Отдай десять страниц. Смотри на карту сайта. Добавляй варианты, когда реальные страницы просят, а не раньше.

Прочитали? К делу

Эти методы я применяю на платных проектах. Посмотрите, во сколько это обходится.