# A/B-сплит лендингов через JS-редирект

## Назначение
Скрипт делит трафик с одного лендинга между несколькими вариантами (A/B/C…). Все GET-параметры (UTM и прочие) и `#hash` сохраняются. Выпавший вариант закрепляется за посетителем.

## Куда ставить
- Только на **исходную страницу** (вариант A).
- В **`<head>`** страницы (настройки страницы → код в head). Если вставить скрипт в HTML-блок, перед редиректом будет виден контент.
- На страницы других вариантов (B, C…) скрипт **не ставится**.

## Настройки
| Переменная | Назначение |
|---|---|
| `SOURCE_PATH` | Путь страницы, на которой запускается сплит (без домена). На других страницах скрипт не срабатывает, это защищает от цикла. |
| `STORAGE_KEY` | Имя ключа в `localStorage`, где хранится выпавший вариант. Уникален для каждого теста. Смена ключа перераспределяет всех заново. |
| `VARIANTS` | Список вариантов: `name`, `url`, `weight`. Вес задаёт долю трафика (`2,1,1` = 50/25/25). |

## Как работает
1. Если путь ≠ `SOURCE_PATH`, скрипт останавливается.
2. Страница скрывается, чтобы не было мелькания. Через 3 сек срабатывает страховочный показ.
3. Из `localStorage` берётся сохранённый вариант. Если его нет, вариант выбирается случайно с учётом весов и сохраняется.
4. Если выпал вариант A (текущая страница), страница показывается без редиректа.
5. Иначе происходит редирект (`location.replace`) на URL варианта со всеми параметрами и hash.

## Где хранится вариант
- В `localStorage` браузера посетителя, на сервере ничего нет.
- Выбор привязан к браузеру, устройству и домену. С другого устройства, в инкогнито или после очистки данных посетитель распределяется заново.
- Хранится бессрочно.
- Проверить или сбросить: DevTools → Application → Local Storage → домен → ключ `STORAGE_KEY`. Для своих тестов удобнее режим инкогнито.

## Ограничения
- Целевые URL должны иметь путь, отличный от `SOURCE_PATH`, иначе будет цикл.
- Метка группы в URL не передаётся. Вариант определяется по адресу лендинга.

## Скрипт (пример: intensiv)
```html
<script>
(function () {
  // ===== НАСТРОЙКИ =====
  var SOURCE_PATH = '/intensiv-a';
  var STORAGE_KEY = 'ab_intensiv_2026_10';

  var VARIANTS = [
    { name: 'a', url: 'https://edu.baniilatreaba.ro/intensiv-a', weight: 1 },
    { name: 'b', url: 'https://edu.baniilatreaba.ro/intensiv-b', weight: 1 },
    { name: 'c', url: 'https://edu.baniilatreaba.ro/intensiv-c', weight: 1 }
  ];
  // =====================

  var current = new URL(window.location.href);
  if (current.pathname !== SOURCE_PATH) return;

  // Сразу скрываем страницу
  var html = document.documentElement;
  html.style.visibility = 'hidden';
  function show() { html.style.visibility = ''; }
  // Страховка: показать через 3 сек
  var failsafe = setTimeout(show, 3000);

  var saved = null;
  try { saved = localStorage.getItem(STORAGE_KEY); } catch (e) {}
  var variant = VARIANTS.filter(function (v) { return v.name === saved; })[0];

  if (!variant) {
    var total = VARIANTS.reduce(function (s, v) { return s + (v.weight || 1); }, 0);
    var r = Math.random() * total;
    for (var i = 0; i < VARIANTS.length; i++) {
      r -= (VARIANTS[i].weight || 1);
      if (r < 0) { variant = VARIANTS[i]; break; }
    }
    variant = variant || VARIANTS[0];
    try { localStorage.setItem(STORAGE_KEY, variant.name); } catch (e) {}
  }

  var target = new URL(variant.url, current.origin);

  // Вариант = текущая страница → показываем и остаёмся
  if (target.origin === current.origin && target.pathname === current.pathname) {
    clearTimeout(failsafe);
    show();
    return;
  }

  // Переносим все параметры и hash
  current.searchParams.forEach(function (value, key) {
    target.searchParams.append(key, value);
  });
  target.hash = current.hash;

  window.location.replace(target.toString());
})();
</script>
```