Skip to content

События виджета ​

У виджета два канала общения с сайтом:

  1. Единая шина SearchForceWidget.push(['имя', данные]) / .on(имя, обработчик) — через неё уходит аналитика (корзина, покупка, клики) и можно обмениваться любыми своими сообщениями между карточкой, скриптами тенанта и сайтом.
  2. DOM-события (CustomEvent) — узкие хуки для управления переходом по поиску, когда вы хотите маршрутизировать его сами (SPA, нестандартный роутинг).

Единая шина: push() / on() ​

js
// сайт СООБЩАЕТ виджету о действии (аналитика уходит сама)
window.SearchForceWidget = window.SearchForceWidget || [];
SearchForceWidget.push(['addToCart', { objectId: 12345, amount: '2599.00' }]);
SearchForceWidget.push(['purchase', { orderId: 'A-10042', amount: '2599.00' }]);

// сайт СЛУШАЕТ события виджета (нужен уже загруженный скрипт)
const off = SearchForceWidget.on('addToCart', (payload) => { /* … */ });
off(); // отписка

push(...) — единственный вход для отправки. Он же очередь готовности: до загрузки скрипта виджета события копятся в массиве и уходят, как только он появится, — поэтому вызывать можно в любой момент и не важно, как подключён виджет (обычный тег, async, вставка через GTM). Известные события встроенный подписчик доставляет в аналитику сам:

СобытиеpayloadВ аналитику
productClick{ hit } (из поиска) или { objectId }клик, с атрибуцией к поиску если есть
addToCart{ objectId, amount? } или { hit }добавление в корзину
purchase{ orderId, amount?, objectIds? }покупка (идемпотентна по orderId)

Подписка on(...) требует уже загруженного скрипта виджета: обработчики в очередь не кладутся — вешайте их из своего кода после подключения виджета или внутри SearchForceWidget.ready(...).

Что виджет эмитит сам ​

Эти события шина отдаёт вам — подписывайтесь, чтобы ставить цели в своей аналитике (Яндекс.Метрика, GA4, VK) или связывать поиск с логикой сайта. В нашу аналитику они НЕ уходят повторно: поиски мы пишем на сервере из самого запроса, клик уже посчитан событием productClick.

СобытиеpayloadКогда
open{ surface: 'autocomplete' | 'fullpage' }покупатель открыл поиск: развернул оверлей либо на странице появилась полная выдача
search{ query, nbHits, queryId? }получена выдача — на каждый запрос, включая ввод по буквам
searchSettled{ query, nbHits, queryId? }покупатель перестал печатать (пауза 1,5 с) — один раз на серию набора
noResults{ query }серия набора закончилась пустой выдачей
resultClick{ objectId, queryId?, position? }клик именно по результату поиска
diagnostic{ scope, reason, message }виджет отверг ваш вызов

Для целей во внешней аналитике берите searchSettled, а не search: живой поиск отправляет запрос на каждый ввод, и одно слово даст десяток срабатываний. Запросы короче двух символов и служебные (*) не эмитятся вовсе — тем же порогом мы считаем поиски на сервере.

Для Яндекс.Метрики руками писать ничего не нужно

Готовый набор целей и виртуальные хиты поиска включаются в кабинете одной галочкой — см. Яндекс.Метрика. Слушайте события сами, только если нужна своя логика или другая система аналитики.

Пример своей цели: «искал» в GA4 один раз за визит.

js
SearchForceWidget.on('searchSettled', ({ query, nbHits }) => {
  if (typeof gtag !== 'function' || sessionStorage.getItem('sf_search_goal')) return;
  sessionStorage.setItem('sf_search_goal', '1');
  gtag('event', 'view_search_results', { search_term: query, results_count: nbHits });
});

Помните, что query — текст, который набрал покупатель: в поиск иногда вводят телефоны и адреса, поэтому решайте осознанно, отправлять ли его в чужую систему.

Обратно виджет эмитит diagnostic — когда отверг ваш вызов (неверный формат поля). Подпишитесь, если хотите видеть такие отказы в своём мониторинге, а не только в консоли браузера:

js
SearchForceWidget.on('diagnostic', ({ scope, reason, message }) => {
  // message — тот же текст, что виджет печатает в console.warn
  myMonitoring.warn(message, { event: scope, reason });
});

objectId/orderId — строка или число. amount — сумма в основных единицах валюты проекта (рубли, не копейки): '2599.00' или 2599; необязательна, но без неё не наберутся отчёты выручки. Правила разбора и что происходит при неверном формате — в «Трекинг → Корзина и покупки».

Полные примеры для корзины и чекаута — в «Трекинг → Корзина и покупки». Неизвестные имена событий аналитика игнорирует — шину можно использовать под свои сообщения.

Клики по товарам виджет репортит сам

Клик по карточке в выдаче и подсказках уходит в аналитику автоматически (с атрибуцией queryID/позиции) — пушить productClick вручную нужно только для кликов вне поиска.

DOM-события: управление переходом по поиску ​

Летят на элементе-триггере из autocomplete.init({ input }), всплывают (bubbles: true) — слушать можно и на нём, и на document:

js
document.addEventListener('sf:search-submit', function (e) {
  console.log('Поисковый запрос:', e.detail.query);
});

sf:search-submit ​

Срабатывает при отправке запроса (Enter, «Показать все результаты», выбор из истории/популярных/категорий) — только если searchUrl не задан. С заданным searchUrl виджет вместо события переходит на страницу выдачи.

Поле detailКогдаЗначение
queryобычный текстовый запросСтрока запроса.
query + refinementsвыбор категории из подсказокquery: '' и refinements: { <поле-фасет>: [значение] }.
js
document.addEventListener('sf:search-submit', function (e) {
  var params = new URLSearchParams();
  if (e.detail.query) {
    params.set('q', e.detail.query);
  }
  myRouter.push('/search/?' + params.toString()); // ваш роутер
});

Скрипты тенанта ​

Логику связи виджета с сайтом можно вынести в скрипты тенанта (scripts.ts), которые редактируются в редакторе виджета и запекаются в бандл. Они получают ту же шину и выполняются один раз при загрузке:

ts
import { defineTenantScripts } from '@searchforce/runtime'

export default defineTenantScripts(({ events }) => {
  events.on('addToCart', (payload) => {
    // вызвать API корзины сайта
  });

  // Цель «искал» в Метрике клиента — один раз за визит.
  events.on('searchSettled', () => {
    // тот же код, что выше; в скриптах тенанта подписка доступна сразу,
    // ждать загрузки бандла не нужно — они его часть.
  });
});

Полностраничная выдача синхронизирует запрос и фильтры с URL сама (параметр enableRouting, см. справочник виджетов).