Интеграция с SPA
В одностраничном приложении переход между разделами не перезагружает страницу:
ядро само не узнаёт, что контекст сменился. Поэтому приложение сообщает о
переходах явно — вызовом GF.API('spa', …).
Базовая установка описана на странице Установка скрипта — здесь только то, что добавляется для SPA.
Два варианта установки
Выбор зависит от одного: известен ли контекст страницы в момент, когда сервер отдаёт HTML.
Вариант 1. Контекст известен при загрузке страницы
Подходит, если приложение рендерится на сервере или тип страницы можно определить сразу — например, по URL маршрута.
<script>
window.GF = window.GF || {};
GF.q = GF.q || [];
GF.API = GF.API || function () { GF.q.push(arguments); };
GF.section = "ИДЕНТИФИКАТОР_СЕКЦИИ";
GF.pageContext = { type: "PRODUCT", data: ["SKU-12345"] };
</script>
<script src="//cdn-01.gravityfield.ai/core/core.js"></script>
Сниппет тот же, что и при обычной установке. Ядро запускает кампании сразу при
загрузке и само отправляет просмотр страницы. О последующих переходах
приложение сообщает событием spa.
Вариант 2. Контекст известен только приложению
Подходит, если на момент загрузки HTML тип страницы неизвестен — контекст
появляется, когда отработает роутер. Добавьте GF.isSpa = true:
<script>
window.GF = window.GF || {};
GF.q = GF.q || [];
GF.API = GF.API || function () { GF.q.push(arguments); };
GF.section = "ИДЕНТИФИКАТОР_СЕКЦИИ";
GF.isSpa = true;
</script>
<script src="//cdn-01.gravityfield.ai/core/core.js"></script>
С этим флагом ядро не запускает кампании на старте, а ждёт первого события
spa — чтобы не проверять таргетинг по ещё неизвестному контексту. Отсюда
два следствия:
-
отправьте
spaдля стартового маршрута сразу, как только приложение узнало контекст, — иначе на первой странице не покажется ни одна кампания; -
просмотр первой страницы ядро само не засчитывает, поэтому в стартовом событии нужен
countAsPageview: true.
Зачем нужна очередь GF.q
Роутер обычно сообщает о стартовом маршруте в момент инициализации
приложения — то есть, скорее всего, ещё до того, как core.js догрузится.
Очередь из сниппета сохраняет этот вызов и передаёт ядру, когда оно будет
готово. Без неё стартовое событие пропадёт, и кампании на первой странице
не появятся.
Загрузка конфигурации своими силами
По умолчанию ядро загружает конфигурацию секции (dynamic.js) само. Если вы
хотите управлять этим — например, отдавать файл со своего домена, — включите
GF.syncLoad = true и подключите его тегом. Тег dynamic.js должен идти
перед core.js:
<script>
window.GF = window.GF || {};
GF.q = GF.q || [];
GF.API = GF.API || function () { GF.q.push(arguments); };
GF.section = "ИДЕНТИФИКАТОР_СЕКЦИИ";
GF.isSpa = true;
GF.syncLoad = true;
</script>
<script src="//cdn-01.gravityfield.ai/sections/ИДЕНТИФИКАТОР_СЕКЦИИ/dynamic.js"></script>
<script src="//cdn-01.gravityfield.ai/core/core.js"></script>
В этом варианте preload из базового сниппета не нужен — файл и так подключён
обычным тегом. Если поставить теги в обратном порядке, ядро запустится раньше
конфигурации и будет ждать её появления, добавляя лишнюю задержку к каждой
загрузке страницы.
При GF.syncLoad = true ядро ждёт конфигурацию сколько потребуется. Если
dynamic.js не загрузится, кампании не покажутся. Убедитесь, что файл
отдаётся на всех страницах, где стоит ядро.
Режим syncLoad не связан с isSpa — его можно включать и без SPA.
Событие перехода
GF.API('spa', {
context: {
type: 'PRODUCT',
data: ['SKU-12345']
},
url: 'https://store.example.com/product/SKU-12345',
countAsPageview: true
});
Когда вызывать
- При каждой смене маршрута — с
countAsPageview: true. - При смене контекста без смены маршрута — например, переключение товара внутри одной карточки или смена языка либо валюты — с тем контекстом, который стал актуальным.
Вызывайте после того, как приложение обновило маршрут и знает новый контекст. Ждать окончания отрисовки не нужно: если кампания привязана к элементу, ядро дождётся его появления само.
Когда не вызывать
Событие spa — это не «что-то поменялось в DOM». Каждый вызов запускает полный
цикл: перепроверку таргетинга всех SPA-кампаний и плейсментов, обновление
вставок и новый показ (impression) для каждой сработавшей кампании.
Поэтому не отправляйте spa на раскрытие аккордеона, открытие модального окна,
подгрузку следующей порции бесконечного списка и подобные изменения внутри
одного экрана — это исказит статистику показов и создаст лишнюю нагрузку. Для
таких случаев используйте триггер «ожидание элемента» в настройках кампании или
обычные события.
Поведение кампаний при переходе
Режим SPA у кампании
В настройках кампании (и рекламного плейсмента) есть флаг работы в SPA. Перезапускаются при переходе только кампании с этим флагом. Кампания без него отрабатывает один раз при загрузке страницы и на смену маршрута не реагирует.
Если кампания настроена и работает при полной перезагрузке, но не появляется после перехода — в первую очередь проверьте этот флаг.
Что происходит со вставками
При получении события spa ядро:
-
Убирает из своего реестра вставки, которые уже удалил сам фреймворк при перерисовке маршрута.
-
Для оставшихся вставок SPA-кампаний перепроверяет условия таргетинга в новом контексте. Если условия больше не выполняются — вставка удаляется.
-
Заново проверяет SPA-кампании и плейсменты для нового контекста. Если кампания срабатывает повторно, её прежний блок заменяется на месте, а не дублируется рядом.
Всплывающие окна и уведомления (overlay, notification) живут своим циклом:
переход маршрута их не закрывает.
Рекомендация по разметке
Размещайте целевые контейнеры для вставок внутри компонентов приложения, а не в общем каркасе страницы. Тогда фреймворк сам удалит вставку при смене маршрута, а ядро это увидит и корректно вставит блок заново. Контейнеры, живущие вне зоны перерисовки, приходится снимать по результату перепроверки таргетинга — это работает, но менее предсказуемо.
Очистка эффектов из кода кампании
Если JS-код кампании навешивает обработчики, заводит таймеры или меняет что-то за пределами своего блока, зарегистрируйте функцию очистки:
GF.Utils.onCampaignRemove('ИДЕНТИФИКАТОР_КАМПАНИИ', function () {
// снять обработчики, остановить таймеры и т.п.
});
Она вызовется один раз, когда вставка кампании будет удалена или заменена — при смене маршрута или при повторном показе. При новом показе код кампании выполнится заново и может зарегистрировать хук снова.
Если кампания не перезапустилась
-
Не включён режим SPA у кампании или плейсмента — самая частая причина.
-
Не отправлено событие
spaдля этого перехода либо в нём не обновлёнcontext. -
Условия таргетинга не подходят новому контексту.
-
Предыдущий запуск ещё ждёт свой триггер — например, кампания с триггером «время на странице» или «событие», который так и не сработал. Пока триггер занят, повторный запуск на этом переходе пропускается.
-
На первой странице ничего не показалось при
isSpa: true— стартовое событиеspaне дошло до ядра; проверьте, что в сниппете есть очередьGF.q.
Подробный лог решений по каждой кампании включается в консоли:
GF.Log.enable(); // затем совершить переход
GF.Log.disable();