# A/B-тесты Модуль `experiments` распределяет посетителей между вариантами, применяет вариант к публичной странице и считает показы и конверсии. Назначение стабильно: посетитель получает один вариант эксперимента на всём сроке cookie. ## Проверка представлений Цель **Представление** сравнивает два оформления одного набора данных без изменения запроса или рубрики. Для каждого варианта выбирается опубликованное представление. Если эксперимент выключен или вариант недоступен, AVE.cms использует обычное назначение представления. ## Цели эксперимента | Цель | Ключ цели | Поведение | | --- | --- | --- | | API или тег | Не требуется | Вариант получает собственный компонент или тег `[mod_experiment:code]`. | | Обычный блок | ID блока | Модуль автоматически оборачивает результат блока. | | Системный блок | ID системного блока | Модуль автоматически оборачивает результат системного блока. | | CSS-селектор | Например, `#buy-button` | Вариант применяется к найденным DOM-элементам. | | Цена | CSS-селектор цены | Меняется только отображаемый текст цены. | Режим **Цена** не меняет цену товара, корзины, заказа или платежа. Для теста расчётной цены нужен отдельный проектный обработчик `experiments.assignment.resolved` и серверная проверка на всех этапах заказа. ## Варианты Эксперимент содержит минимум два варианта. Вес задаёт относительную долю, а охват - процент посетителей, участвующих в тесте. Payload варианта поддерживает: - `control` - оставить исходное содержимое; - `replace` - заменить содержимое цели; - `before` и `after` - вставить HTML рядом с целью; - замену текста, добавление CSS-класса и ссылки; - отображаемое значение цены. Эксперимент можно оставить черновиком, запустить, приостановить или завершить. Период начала и окончания необязателен. ## Вставка в шаблон ```text [mod_experiment:promo_button] ``` На месте тега создаётся стабильный слот. Вариант загружается после получения страницы, поэтому общий full-page cache не смешивает варианты разных посетителей. Для автоматической фиксации конверсии добавьте атрибут кнопке или ссылке: ```html ``` Произвольное событие задаётся вторым атрибутом: ```html Оформить ``` Из JavaScript событие можно отправить вручную: ```javascript window.AVEExperiments.convert('promo_button', 'form_sent'); ``` ## Публичный API ```text GET /api/v1/experiments/{code} GET /api/v1/experiments/assignments?codes=promo_button,hero_title POST /api/v1/experiments/event ``` Последний endpoint принимает `code` и `event`. ID варианта от клиента не принимается: сервер повторно вычисляет назначение и записывает событие только в этот вариант. Для одного посетителя уникальность события считается раз в день, при этом общее число событий также сохраняется. ## Hooks ### `experiments.assignment.resolved` Вызывается после серверного выбора варианта. В контексте доступны: - `experiment` - полная запись эксперимента; - `variant` - выбранный вариант; - `visitor_hash` - обезличенный хеш посетителя. Результатом события является массив назначения. Обработчик может вернуть изменённый массив, например для проектной интеграции с сервисным слоем. ### `experiments.event.recorded` Вызывается после записи события. Контекст содержит `experiment`, `variant`, `event_code` и флаг `unique`. ## Кеш и приватность В HTML кешируется только одинаковый для всех слот и конфигурация активных целей. Назначение запрашивается клиентом через API. Случайный seed хранится год в cookie `ave_experiment_seed` с `HttpOnly`, `SameSite=Lax` и `Secure` на HTTPS. IP и исходный seed в статистике не сохраняются. ## Права и удаление - `view_experiments` - просмотр экспериментов и результатов; - `manage_experiments` - создание, запуск, сброс статистики и удаление. Деинсталляция удаляет эксперименты, варианты, статистику, дедупликацию посетителей и настройки модуля.