# Динамический контент в варианте персонализации

Внутри каждого варианта персонализации можно добавлять как статический, так и динамический контент. Если нужно реагировать на данные посетителя — город, устройство, UTM-метки, погоду, время суток — используйте JavaScript-код прямо в шаблоне.

Это позволяет, например:

  • Показывать название города посетителя в заголовке
  • Менять призыв к действию в зависимости от устройства
  • Подставлять количество клиентов в регионе
  • Предлагать разные акции в рабочие и выходные дни
  • Адаптировать текст под погодные условия

# Как это работает

Внутри поля "Контент" можно вставить JavaScript-код в двойных фигурных скобках (например, {{ return "Привет"; }}). Система обработает код на сервере и подставит результат перед отправкой контента в браузер посетителя.

Доступны все стандартные функции JavaScript: Math, String, Array, условные операторы, циклы и т.д.

Важно:

  • Если код выполнится с ошибкой — посетитель увидит контент без изменений, страница не сломается
  • Код выполняется в изолированной среде — нет доступа к DOM, window, fetch или другим браузерным API
  • Каждый JS-блок в двойных фигурных скобках выполняется независимо

# Базовые примеры

# Простое выражение

Сумма 2 + 2 = {{2+2}}

Результат: Сумма 2 + 2 = 4

Для простых выражений без условий можно опустить return. Но если код содержит несколько строк или условия — используйте return явно.

# Условный оператор

10 больше двух? - {{
  if (10 > 2) {
    return "Да";
  } else {
    return "Нет";
  }
}}

Результат: 10 больше двух? - Да

# Тернарный оператор

Для коротких условий удобен тернарный оператор:

Скидка: {{data.session.number > 1 ? "10% для постоянных клиентов" : "5% на первый заказ"}}

# Вложенные функции

Сумма 99 и 1 равна {{
  function sum(arg1, arg2) {
    return arg1 + arg2;
  }
  return sum(99, 1);
}}

Результат: Сумма 99 и 1 равна 100

Если используете вложенные функции — не забывайте явно возвращать результат через return.

# Несколько скриптов в одном контенте

В одном поле контента может быть сколько угодно JS-блоков в двойных фигурных скобках:

{{5 + 5}} больше {{4 - 2}}? - {{return "Да";}}

Результат: 10 больше 2? - Да

Будьте аккуратны: большое количество скриптов может замедлить вычисление контента.


# Контекст: переменная data

Внутри JS-кода доступна переменная data — объект с информацией о текущем посетителе. Данные собираются автоматически при каждом визите: по IP определяется город, по User-Agent — устройство, по URL — UTM-метки, со страницы — Schema.org разметка.

Все поля data доступны только для чтения.


# Практические примеры

# Город и регион посетителя

Самый популярный сценарий — подстановка города в текст:

Доставка в г. {{data.geo.city.nativeName}} за 1 день

Результат для москвича: Доставка в г. Москва за 1 день

Для регионального контента:

{{
  let city = data.geo.city.nativeName;
  if (!city) {
    return "Доставка по всей России";
  }
  return "Доставка в " + city + " и " + data.geo.region.nativeName;
}}

Всегда проверяйте data.geo.city.nativeName на null — город определяется по IP и может быть неизвестен (например, при использовании VPN).

# Столица или нет

{{
  if (data.geo.city.isCountryCapital) {
    return "Бесплатная доставка по Москве";
  } else if (data.geo.city.isRegionCapital) {
    return "Бесплатная доставка по областному центру";
  } else {
    return "Доставка от 300 ₽";
  }
}}

# Размер города

{{
  let pop = data.geo.city.population;
  if (!pop) return "Доставка по вашему городу";
  if (pop > 1000000) {
    return "Доставка по городу-миллионнику — от 0 ₽";
  } else if (pop > 100000) {
    return "Доставка по вашему городу — от 200 ₽";
  } else {
    return "Доставка до пункта выдачи — от 350 ₽";
  }
}}

# Приветствие по времени суток

{{
  if (data.dateAndTime.isMorning) {
    return "Доброе утро! ☀️";
  } else if (data.dateAndTime.isNight) {
    return "Не спится? У нас скидка на ночные заказы 🌙";
  } else if (data.dateAndTime.isWeekend) {
    return "Отличных выходных! 🎉";
  } else {
    return "Добрый день!";
  }
}}

# Контент по часу

{{
  let hour = data.dateAndTime.clientLocalHour;
  if (hour >= 9 && hour < 18) {
    return "Менеджер онлайн — ответим за 5 минут";
  } else {
    return "Оставьте заявку — ответим утром";
  }
}}

# Выходные и рабочие дни

{{
  if (data.dateAndTime.isWeekend) {
    return "В выходные скидка 15% на весь каталог!";
  } else {
    return "Скидка 10% при заказе до конца рабочей недели";
  }
}}

# Адаптация под устройство

{{
  if (data.device.deviceType === "Smartphone") {
    return "Скачайте наше приложение — скидка 20%";
  } else if (data.device.deviceType === "Tablet") {
    return "Удобный каталог для планшета";
  } else {
    return "Полный каталог на десктопе";
  }
}}

# Контент по браузеру

{{
  if (data.device.browser === "Safari" || data.device.os === "iOS") {
    return "Оплата через Apple Pay";
  } else {
    return "Оплата картой или через SberPay";
  }
}}

# Контент по UTM-меткам

{{
  let source = data.utm.source;
  if (source === "google") {
    return "Нашли нас в Google? Вот промокод: GOOGLE10";
  } else if (source === "yandex") {
    return "Пришли из Яндекса? Промокод: YANDEX10";
  } else {
    return "Промокод для новых клиентов: WELCOME10";
  }
}}

# По рекламной кампании

{{
  let campaign = data.utm.campaign;
  if (campaign && campaign.indexOf("black_friday") !== -1) {
    return "🖤 Чёрная пятница — скидки до 70%!";
  } else if (campaign && campaign.indexOf("summer") !== -1) {
    return "☀️ Летняя распродажа!";
  } else {
    return "Специальное предложение";
  }
}}

# Погода

{{
  let temp = data.weather.temp;
  if (temp === null) return "Бесплатная доставка";
  if (temp < 0) {
    return "На улице " + temp + "°C — закажите горячий чай с доставкой ☕";
  } else if (temp > 30) {
    return "Жара " + temp + "°C! Прохладительные напитки со скидкой 🧊";
  } else {
    return "Доставка при любой погоде";
  }
}}

Погодные данные определяются по городу посетителя. Если город не определён — data.weather.temp будет null.

# Повторные визиты

{{
  let sessionNum = data.session.number;
  if (sessionNum === 1) {
    return "Добро пожаловать! Скидка 5% на первый заказ";
  } else if (sessionNum <= 3) {
    return "Рады видеть вас снова! Бесплатная доставка на второй заказ";
  } else {
    return "Для постоянных клиентов — персональная скидка 15%";
  }
}}

# Время на сайте

{{
  let duration = data.session.durationSec;
  if (duration > 300) {
    return "Долго выбираете? Давайте поможем — напишите в чат!";
  } else {
    return "";
  }
}}

# Количество просмотренных страниц

{{
  let pages = data.session.pagesOpenedInThisSession;
  if (pages >= 5) {
    return "Вы посмотрели уже " + pages + " страниц. Может, пора заказать? 😉";
  } else {
    return "";
  }
}}

# Цена товара со страницы (Schema.org)

Если на странице есть Schema.org-разметка (HTML Microdata или JSON-LD), данные автоматически извлекаются:

{{
  let price = data.page.schemaOrg.offer.price;
  if (price && price > 5000) {
    return "При заказе от 5 000 ₽ — бесплатная доставка!";
  } else {
    return "Доставка от 300 ₽";
  }
}}

# Рейтинг товара

{{
  let rating = data.page.schemaOrg.aggregateRating.ratingValue;
  let reviews = data.page.schemaOrg.aggregateRating.reviewCount;
  if (rating && rating >= 4.5 && reviews > 10) {
    return "⭐ Хит продаж! Рейтинг " + rating + " (" + reviews + " отзывов)";
  } else {
    return "";
  }
}}

# Комбинация нескольких параметров

{{
  let city = data.geo.city.nativeName || "вашем городе";
  let device = data.device.deviceType;
  let isWeekend = data.dateAndTime.isWeekend;

  let text = "Доставка в " + city;
  if (isWeekend) {
    text += " работает и в выходные!";
  }
  if (device === "Smartphone") {
    text += " Закажите через приложение — скидка 5%.";
  }
  return text;
}}

# Шаблонные функции

# simulateCityClients(min, max)

Возвращает правдоподобное количество клиентов в городе посетителя. Учитывает население города, размер агломерации и экономический индекс. Результат всегда находится в диапазоне от min до max.

Количество выполненных заявок в вашем городе — {{ simulateCityClients(500, 2000) }}

Результат для Москвы: Количество выполненных заявок в вашем городе — 1847 Результат для небольшого города: Количество выполненных заявок в вашем городе — 612

Если город не определён, возвращается среднее значение (min + max) / 2.

Пример с контекстом:

Уже {{simulateCityClients(100, 800)}} клиентов в г. {{data.geo.city.nativeName || "вашем регионе"}} выбрали нас

# log(message)

Записывает сообщение в лог для отладки. Не влияет на результат и не виден посетителю.

{{
  log("City: " + data.geo.city.nativeName);
  log("Session: " + data.session.number);
  return "Привет!";
}}

# Полный справочник параметров data

# Геолокация: город

Параметр Описание Тип Пример
data.geo.city.nativeName Название на родном языке string "Москва", "Paris"
data.geo.city.englishName Название на английском string "Moscow"
data.geo.city.russianName Название на русском string "Москва", "Париж"
data.geo.city.isRegionCapital Столица региона bool true
data.geo.city.isCountryCapital Столица страны bool true
data.geo.city.population Население number 12500000
data.geo.city.agglomerationPopulation Население агломерации number 17100000
data.geo.city.averageSalaryUSD Средняя зарплата (USD) number 99.9
data.geo.city.economicLocalIndex Экономический индекс (0–100) number 75.3

# Геолокация: регион

Параметр Описание Тип Пример
data.geo.region.nativeName Название на родном языке string "Московская область"
data.geo.region.englishName Название на английском string "Moscow Oblast"
data.geo.region.russianName Название на русском string "Московская область"
data.geo.region.population Население региона number 7500000

# Геолокация: страна

Параметр Описание Тип Пример
data.geo.country.nativeName Название на родном языке string "Россия"
data.geo.country.englishName Название на английском string "Russia"
data.geo.country.russianName Название на русском string "Россия"
data.geo.country.population Население страны number 146000000

# Данные страницы

Параметр Описание Тип Пример
data.page.pageClearedUrl URL страницы (без трекинг-параметров) string "/catalog/phones"
data.page.pageTitle Заголовок страницы string "Каталог телефонов"

# Данные страницы: Schema.org

Автоматически извлекаются из HTML Microdata и JSON-LD разметки на странице.

Параметр Описание Тип Пример
data.page.schemaOrg.brandName Бренд string "Apple"
data.page.schemaOrg.offer.price Цена number 99990
data.page.schemaOrg.offer.availability Наличие string "InStock"
data.page.schemaOrg.aggregateRating.ratingValue Средний рейтинг number 4.5
data.page.schemaOrg.aggregateRating.reviewCount Количество отзывов number 120

# Погода

Определяется по городу посетителя. Если город не определён — все значения null.

Параметр Описание Тип Пример
data.weather.temp Температура (°C) number 22.5
data.weather.tempFeelsLike Ощущаемая температура (°C) number 20.0
data.weather.humidity Влажность (%) number 65

# Устройство

Параметр Описание Тип Возможные значения
data.device.browser Браузер string "Chrome", "Safari", "Edge", "Opera", "Firefox", "YandexBrowser", "InternetExplorer", "Other"
data.device.deviceType Тип устройства string "Desktop", "Smartphone", "Tablet", "Other"
data.device.os Операционная система string "Windows", "MacOs", "Linux", "iOS", "Android", "Other"

# UTM-метки

Параметр Описание Тип Пример
data.utm.source Источник string "google"
data.utm.medium Канал string "cpc"
data.utm.campaign Кампания string "summer_sale"
data.utm.content Контент string "banner_1"
data.utm.term Ключевое слово string "best_deals"

# Дата и время

Время определяется по часовому поясу посетителя.

Параметр Описание Тип Пример
data.dateAndTime.clientLocalHour Локальный час (0–23) number 14
data.dateAndTime.dayOfWeekNumber День недели (1–7) number 3
data.dateAndTime.weekNumberInMonth Неделя в месяце (1–5) number 2
data.dateAndTime.isNight Ночь (22:00–06:00) bool false
data.dateAndTime.isMorning Утро (06:00–11:00) bool true
data.dateAndTime.isWeekend Выходной bool false

# Сессия

Параметр Описание Тип Пример
data.session.number Номер визита пользователя (начиная с 1) number 3
data.session.durationSec Длительность текущей сессии (секунды) number 245.5
data.session.pagesOpenedInThisSession Страниц открыто в текущей сессии number 5

# Обработка ошибок и null-значений

Любое поле data может быть null — например, если город не определён по IP или на странице нет Schema.org-разметки. Всегда проверяйте значения перед использованием:

// ❌ Плохо — упадёт если город не определён
Доставка в {{data.geo.city.nativeName}}

// ✅ Хорошо — с проверкой
Доставка в {{data.geo.city.nativeName || "ваш город"}}

// ✅ Хорошо — развёрнутая проверка
{{
  let city = data.geo.city.nativeName;
  if (city) {
    return "Доставка в " + city;
  }
  return "Доставка по России";
}}

Если код внутри JS-блока выбросит ошибку, посетитель увидит контент без этой подстановки — страница не сломается.


# Советы

  • Начинайте с простого. Подставьте город в заголовок — это уже даст персонализированный контент
  • Проверяйте null. Самая частая ошибка — обращение к полю, которое не определено
  • Тестируйте в отладке. Используйте отладочный режим, чтобы увидеть результат шаблонов на реальной странице
  • Используйте log(). Для отладки сложных шаблонов записывайте промежуточные значения
  • Комбинируйте условия. Самые эффективные шаблоны учитывают несколько параметров — город + устройство + время

# Следующие шаги