Користувацькі лендинги
Що таке користувацький лендинг
Користувацький (hosted) лендинг — це довільна HTML-сторінка, завантажена в систему у вигляді ZIP-архіву. Вона відображається користувачу в рамках Flow кампанії: після переходу за трекінговим посиланням і до редиректу на офер.
Лендинг може бути будь-яким за дизайном — колесо фортуни, слот, ігровий екран, форма реєстрації тощо. Платформа автоматично вбудовує в нього необхідну логіку трекінгу та підписки на пуш.
Всі завантажувані лендинги повинні відповідати правилам допустимого використання сервісу.
Структура ZIP-архіву
Архів повинен містити файл index.html (або index.twig) в корені. Усі статичні файли (зображення, CSS, JS, шрифти) повинні знаходитися поряд або у вкладених папках.
landing.zip
├── index.html ← обов'язково
├── style.css
├── script.js
└── images/
└── bg.jpg
Система розгортає архів і роздає файли через S3. Усі шляхи до ассетів всередині HTML обов'язково повинні бути відносними.
Відносні шляхи до ассетів
Платформа публікує лендинг за динамічним URL виду:
https://cdn.example.com/landings/<id>/
Тому всі посилання на файли всередині index.html повинні бути відносними — без ведучого / і без вказівки домену.
Приклади правильних шляхів
<!-- Стилі -->
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="css/main.css">
<!-- Скрипти -->
<script src="script.js"></script>
<script src="js/vendor/gsap.min.js"></script>
<!-- Зображення -->
<img src="images/bg.jpg" alt="background">
<img src="images/logo.png" alt="logo">
<!-- Фонове зображення в CSS -->
<style>
.wheel {
background-image: url('images/wheel.png');
}
</style>
<!-- Шрифти (в style.css) -->
@font-face {
font-family: 'MyFont';
src: url('fonts/myfont.woff2') format('woff2');
}
<!-- Відео -->
<video src="video/promo.mp4" autoplay muted loop></video>
<!-- Аудіо -->
<audio src="sfx/spin.mp3"></audio>
Приклади неправильних шляхів ❌
<!-- Абсолютний шлях від кореня — зламається при публікації -->
<link rel="stylesheet" href="/style.css">
<img src="/images/bg.jpg">
<!-- Повний URL — не буде працювати в оточенні лендинга -->
<script src="https://mysite.com/script.js"></script>
Завантаження лендинга
Перейти на сторінку
/app/landingsНатиснути кнопку Завантажити лендинг
Заповнити форму:
Поле | Обов'язкове | Опис |
|---|---|---|
Logo | Так | Прев'ю-іконка (300×300 px) — відображається в списку, використовується для іконки програми, якщо лендинг використовується в форматі PWA |
Name | Так | Внутрішня назва для ідентифікації в системі |
Title | Так | Заголовок (наприклад, для відображення в PWA) |
ZIP-файл | Так (при створенні) | Архів з файлами лендинга ( |
Active | — | Чи активний лендинг (за замовчуванням увімкнено) |
- Натиснути Save — система завантажить архів, розпакує його і опублікує лендинг
Після успішного завантаження лендинг з'являється в таблиці і доступний для використання в Flow кампанії.
Редагування лендинга
Натиснути кнопку ⋮ навпроти потрібного запису → Редагувати. Можна змінити назву, logo, статус і завантажити нову версію ZIP-архіву.
Поле ZIP необов'язкове при редагуванні — якщо не вибрати новий файл, поточний контент зберігається
Редактор HTML-шаблону
Для кожного лендинга доступне вбудоване редагування файлу index.html прямо в інтерфейсі — без повторного завантаження ZIP-архіву.
Як відкрити
Натиснути кнопку ⋮ навпроти потрібного лендинга
Вибрати Edit Template
Відкриється діалог на весь екран з двома панелями.
Панелі редактора
Панель | Опис |
|---|---|
Редактор (ліва) | Код-редактор з підсвіткою синтаксису для редагування |
Прев'ю (права) | Live-прев'ю: рендерить Twig-шаблон і відображає результат в |

Прев'ю оновлюється автоматично по мірі вводу — дозволяє відразу бачити результат змін верстки без збереження.
Важливо: редактор працює з файлом index.html— основним шаблоном лендинга. Інші файли архіву (CSS, JS, зображення) залишаються без змін.
Збереження
Натиснути Save Template — зміни застосовуються негайно. Новий ZIP завантажувати не потрібно.
Як платформа вбудовує логіку в лендинг
При відображенні лендинга система автоматично додає до HTML блок з необхідними скриптами (landing-includes). Це відбувається на стороні сервера — ніяких правок в HTML робити не потрібно.
Що вбудовується автоматично:
1. Глобальна змінна trackUrl
const trackUrl = '...'; // трекінгове посилання з клік-параметрами
Це посилання, по якому користувач повинен перейти після виконання дії на лендингу. Використовується функцією engine_onClickButton().
2. Функція engine_onClickButton()
Основна функція движка — веде користувача далі по кампанії. Поведінка залежить від контексту:
Контекст | Поведінка |
|---|---|
Звичайний лендинг (без PWA) | Переходить по |
Лендинг з підпискою на пуш | Спочатку запитує підписку, потім переходить по |
Лендинг як PWA | Запускає установку PWA, після установки відкриває додаток |
iOS / fallback | Негайний перехід по |
3. Автоматична прив'язка <a> елементів
Усі <a> теги на сторінці автоматично отримують:
href= значенняtrackUrlобробник кліка, що викликає
engine_onClickButton()
Це означає, що будь-яке посилання на лендингу автоматично веде користувача по Flow — без жодних додаткових налаштувань з вашого боку.
Як використовувати engine_onClickButton() на своїх елементах
Якщо на лендингу є кнопки, div-блоки або інші інтерактивні елементи (не <a>), які повинні вести користувача далі по кампанії — повісьте на них engine_onClickButton через addEventListener:
// Повісити на кнопку
document.getElementById('spin-button').addEventListener('click', engine_onClickButton);
// Повісити на довільний елемент
document.querySelector('.play-btn').addEventListener('click', engine_onClickButton);
// Повісити після DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.cta-button').forEach(el => {
el.addEventListener('click', engine_onClickButton);
});
});
Функція engine_onClickButton вже визначена платформою — вона доступна глобально в window.
Повний приклад лендинга
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Spin & Win</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wheel-container">
<!-- Кнопка spin — a-елемент, обробник навішується автоматично -->
<a class="spin-btn">SPIN</a>
</div>
<!-- Або: звичайна кнопка з ручною прив'язкою -->
<button id="play-btn">Play Now</button>
<script src="wheel.js"></script>
<!-- Блок коду який навішує на клік по кнопці Play Now перехід далі -->
<script>
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('play-btn').addEventListener('click', engine_onClickButton);
});
</script>
</body>
</html>
engine_onClickButton і trackUrl будуть доступні, оскільки платформа автоматично вставляє їх у сторінку перед вашим контентом.
Макрос trackUrl
Якщо потрібно використовувати трекінгове посилання безпосередньо в HTML (наприклад, для href на елементі без JS), система також розкриває змінну trackUrl на сторінці:
<a href="{{ trackUrl }}">Перейти</a>
Однак переважний спосіб — використовувати engine_onClickButton(), оскільки він коректно обробляє всі сценарії (PWA, підписка, звичайний редирект).
Використання лендинга в кампанії
Після завантаження лендинг доступний в налаштуваннях ротації кампанії (розділ /app/campaigns → редагування кампанії → стрім сети → Ротація). Виберіть завантажений лендинг у полі «Landing» всередині потрібного стрім сету.
Часті питання
Чи потрібно вручну додавати трекінгові скрипти в HTML?
Ні. Усі скрипти (підписка, engine_onClickButton, trackUrl) вбудовуються автоматично платформою.
Чому <a href="#"> вже веде по Flow без змін?
Тому що при завантаженні сторінки всі <a> отримують автоматичний href = trackUrl і обробник кліка.
Чи можна використовувати свій JS-фреймворк (React, Vue тощо) всередині лендинга?
Так. Головне — підключати engine_onClickButton через addEventListener після ініціалізації вашого додатку, оскільки функція визначається платформою асинхронно.
Що станеться, якщо ZIP не містить index.html?
Лендинг буде створено, але при спробі відкрити його користувач отримає помилку. Переконайтеся, що index.html знаходиться в корені архіву.
Чи можна оновити лендинг без зміни його ID?
Так. При редагуванні запису і завантаженні нового ZIP — ID лендинга залишається попереднім, оновлюється тільки контент.
