Реализация подмены заголовков лендинга по рекламной кампании

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация подмены заголовков лендинга по рекламной кампании
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация подмены заголовков лендинга по рекламной кампании

Подмена заголовков (headline substitution или dynamic keyword insertion на уровне сайта) — это техника, при которой H1 и подзаголовки лендинга автоматически меняются под рекламное объявление, которое привело пользователя. Если человек кликнул на объявление «Разработка сайта для стоматологии» — он попадает на страницу с заголовком «Разработка сайта для стоматологии», а не на общий лендинг веб-студии.

Принцип работы

Рекламная система передаёт параметры в URL. Либо стандартные UTM, либо кастомные параметры. Сайт читает параметры, находит в словаре нужный заголовок и подставляет его в DOM до того, как пользователь успевает увидеть исходный текст.

Два подхода: параметр в URL напрямую содержит текст (небезопасно — можно подделать) или параметр содержит ключ, по которому сервер/клиент находит заголовок из предзаданного словаря.

Словарь заголовков

// headline-map.js — словарь кампания → заголовок
export const headlineMap: Record<string, HeadlineSet> = {
  // Google Ads — по utm_campaign
  'dental-clinic-sites': {
    h1: 'Сайты для стоматологий — под ключ за 14 дней',
    h2: 'Запись онлайн, личный кабинет пациента, интеграция с МИС',
    breadcrumb: 'Сайты для клиник',
  },
  'lawyer-sites': {
    h1: 'Сайты для юридических компаний',
    h2: 'Конфиденциальность, доверие, форма записи на консультацию',
    breadcrumb: 'Сайты для юристов',
  },
  'ecom-landing': {
    h1: 'Интернет-магазин с нуля — от прототипа до запуска',
    h2: 'Каталог, корзина, оплата, доставка — всё готово',
    breadcrumb: 'Интернет-магазины',
  },

  // По utm_term (ключевое слово)
  terms: {
    'создать сайт': {
      h1: 'Создадим сайт под ваши задачи',
      h2: 'Рассчитайте стоимость за 2 минуты',
    },
    'разработка лендинга': {
      h1: 'Лендинг с конверсией от 5%',
      h2: 'Продаёт 24/7 — пока вы занимаетесь бизнесом',
    },
  },
};

Логика подстановки

interface HeadlineSet {
  h1?: string;
  h2?: string;
  breadcrumb?: string;
}

function resolveHeadlines(): HeadlineSet {
  const params = new URLSearchParams(location.search);
  const campaign = params.get('utm_campaign') ?? sessionStorage.getItem('utm_campaign');
  const term = params.get('utm_term') ?? sessionStorage.getItem('utm_term');

  // Сохраняем для следующих страниц
  if (params.get('utm_campaign')) {
    sessionStorage.setItem('utm_campaign', params.get('utm_campaign')!);
    sessionStorage.setItem('utm_term', params.get('utm_term') ?? '');
  }

  // Приоритет: кампания > ключевое слово > дефолт
  if (campaign && headlineMap[campaign]) return headlineMap[campaign];

  if (term) {
    const termKey = Object.keys(headlineMap.terms ?? {})
      .find(k => term.toLowerCase().includes(k));
    if (termKey) return headlineMap.terms[termKey];
  }

  return {}; // не меняем дефолтный текст
}

function applyHeadlines(headlines: HeadlineSet): void {
  const map: [string, keyof HeadlineSet][] = [
    ['[data-headline="h1"]', 'h1'],
    ['[data-headline="h2"]', 'h2'],
    ['[data-headline="breadcrumb"]', 'breadcrumb'],
  ];

  map.forEach(([selector, key]) => {
    const el = document.querySelector(selector);
    if (el && headlines[key]) {
      el.textContent = headlines[key]!;
    }
  });
}

// Запуск — желательно inline в <head> чтобы не было мерцания
const headlines = resolveHeadlines();
applyHeadlines(headlines);

Разметка HTML

<!DOCTYPE html>
<html>
<head>
  <!-- Скрипт подмены заголовков — до рендера body -->
  <script src="/js/headline-substitution.js"></script>
</head>
<body>
  <nav class="breadcrumb">
    <a href="/">Главная</a> /
    <span data-headline="breadcrumb">Разработка сайтов</span>
  </nav>

  <section class="hero">
    <h1 data-headline="h1">Разработка сайтов для бизнеса</h1>
    <p data-headline="h2">Работаем с 2010 года — более 400 проектов</p>
    <a href="/brief" class="btn-primary">Рассчитать стоимость</a>
  </section>
</body>
</html>

Скрипт подстановки должен быть синхронным в <head>, а не defer/async — иначе пользователь увидит исходный заголовок на долю секунды перед заменой (flash of original content). Скрипт маленький — 1–2 КБ, блокировка рендера незначительна.

Google Ads Dynamic Keyword Insertion vs подмена заголовков

DKI в Google Ads подставляет ключевое слово в объявление. Подмена заголовков на сайте — логическое продолжение: сайт «отвечает» тем же языком, что и объявление. Связка работает через utm_term:

В кампании Google Ads создаётся шаблон URL:

https://example.com/landing?utm_campaign=dental&utm_term={keyword}

Google автоматически подставляет реальное ключевое слово в {keyword}. Сайт читает utm_term и показывает соответствующий заголовок.

Серверная подмена (без мерцания)

Для SSR-проектов подмена на сервере надёжнее:

// LandingController.php
public function index(Request $request): Response
{
    $campaign = $request->get('utm_campaign') ?? $request->session()->get('utm_campaign');
    $term = $request->get('utm_term') ?? $request->session()->get('utm_term');

    if ($request->get('utm_campaign')) {
        $request->session()->put('utm_campaign', $campaign);
        $request->session()->put('utm_term', $term);
    }

    $headlines = HeadlineResolver::resolve($campaign, $term);

    return Inertia::render('Landing', [
        'headlines' => $headlines,
    ]);
}

Проверка корректности подмены

Для QA создаётся специальный режим: при добавлении ?debug_headlines=1 в URL страница показывает все доступные варианты заголовков в виде таблицы — удобно для тестирования перед запуском кампании.

Сроки

Словарь заголовков + JS-подмена на клиенте: 3–5 часов. Серверная подмена с сессией + Inertia: 4–6 часов. QA-режим для проверки всех вариантов: 1–2 часа. Загрузка словаря из CMS (редактируемый список в админке): 1 день.