Акция «Самый дешёвый в подарок» — инструкция
JavaScript для Tilda Store

Акция «Самый дешёвый товар в подарок»

Практическое руководство к скрипту, который считает подарочные позиции в корзине Tilda, применяет скидку, показывает бейджи и передаёт сведения о промоакции в заказ.

Tilda t7063 = 2 / 4 = 3Скидка 0–100%Адаптируется к корзине

Что делает скрипт

В базовой конфигурации покупатель кладёт три разрешённых товара в корзину, а самая дешёвая единица получает скидку 100%. Скрипт работает и с одинаковыми товарами: сравнивает каждую единицу, а не только строки корзины.

01

Загружает каталог

Запрашивает все товары указанной категории Tilda. Каталог нужен, чтобы определить названия товаров и позиции с обычной скидкой.

02

Следит за корзиной

MutationObserver замечает открытие корзины и запускает пересчёт каждые 250 мс только пока она открыта.

03

Обновляет интерфейс

Добавляет пояснение в корзину, перечёркивает полностью бесплатные позиции и заполняет скрытое поле заказа.

Логика в одном взгляде

Корзина открыта
Проверка промокода и каталога
Отбор дешёвых единиц и скидка
Приоритет промокода: если в корзине действует промокод, скрипт снимает только собственную скидку акции. Сам цикл пересчёта продолжает работать — после удаления промокода акция вернётся автоматически.

Подключение

ШАГ 1

Укажите категорию

Найдите ID категории «Все товары» или нужного каталога и замените демонстрационное число в ALL_CATEGORY_ID.

ШАГ 2

Задайте акцию

Настройте массив DEALS: сколько единиц нужно взять и сколько из них оплатить.

ШАГ 3

Вставьте код

Разместите исходный фрагмент HTML/JS в пользовательском HTML-блоке или в коде страницы Tilda. Опубликуйте страницу.

Важно: скрипт рассчитан на стандартные корзины Tilda с CSS-классами t706. Перед публикацией откройте корзину на опубликованной странице и проверьте тестовый заказ.

Основные настройки

Все параметры находятся в самом начале блока <script>. Меняйте только значения справа от знака =.

Конфигурация
const ENABLED_DEFAULT = true;       // включить акцию const DEBUG = true;                 // журнал в консоли браузера const POLL_MS = 250;               // частота пересчёта, мс const ALL_CATEGORY_ID = String(window.id_all_category_p || '434145928791');
const ALLOW_SALE_ITEMS_DEFAULT = false;
const FREEBIE_DISCOUNT_PERCENT_DEFAULT = 100;
const SALE_FREEBIE_POLICY = 'minusOne';
const USE_ALLOWED_LIST_DEFAULT = false;
const FREEBIE_ALLOWED_UIDS = [ // 579586095852, ];
ПараметрНазначениеЧто поставить
ALL_CATEGORY_IDКатегория, из которой подгружается каталог.Реальный ID категории Tilda.
FREEBIE_DISCOUNT_PERCENT_DEFAULTРезервная величина скидки.100 для подарка, 50 для скидки 50%.
USE_ALLOWED_LIST_DEFAULTОграничивает акцию конкретными товарами.true, если используется список UID.
FREEBIE_ALLOWED_UIDSUID товаров или вариаций, доступных для акции.Числа через запятую; при пустом списке и true акция не сработает.
ALLOW_SALE_ITEMS_DEFAULTРазрешает выдавать скидку на уже уценённые товары.Обычно false.
DEBUGВыводит диагностические сообщения с префиксом [CFREE].true при проверке, затем false.

Настройка правил акции

Массив DEALS определяет, сколько единиц покупатель должен взять (buy) и сколько оплатить (pay).

Примеры DEALS
// Базовый вариант: 3 товара, один из них бесплатно; только один раз const DEALS = [{ buy: 3, pay: 2, repeat: false, percent: 100 }];

// Повторяемая акция: при 6 товарах — два подарка const DEALS = [{ buy: 3, pay: 2, repeat: true, percent: 100 }];

// Один подарок при 4 товарах и скидка 50% при 6 товарах const DEALS = [
  { buy: 4, pay: 3, repeat: false, percent: 100 },
  { buy: 6, pay: 5, repeat: false, percent: 50 }
];

// Только 4 = 3: exclusive исключает остальные правила const DEALS = [{ buy: 4, pay: 3, repeat: false, exclusive: true, percent: 100 }];
ПолеСмысл
buyКоличество единиц, необходимое для применения правила.
payКоличество оплачиваемых единиц. Разница buy − pay получит скидку.
repeattrue повторяет правило на каждой кратности; false применяет его максимум раз.
percentПроцент скидки для награждённой единицы.
exclusivetrue оставляет только это правило, игнорируя все остальные.

Управление из консоли

После загрузки страницы доступен объект window.CFREE. Команды удобно выполнять в DevTools → Console во время тестирования.

CFREE.enable() / disable()

Включить или выключить акцию. При выключении скидка и метки удаляются.

CFREE.recalcNow()

Немедленно выполнить пересчёт, не дожидаясь следующего цикла.

CFREE.useAllowedList()

Разрешить акцию только для UID из FREEBIE_ALLOWED_UIDS.

CFREE.useAllProducts()

Снять фильтр и применять акцию ко всем товарам.

CFREE.setFreebieDiscountPercent(50)

Временно установить резервную скидку в процентах.

CFREE.allowSaleItems()

Разрешить выбирать уже уценённые позиции как подарочные.

Проверка перед запуском

1

Проверьте порог

Добавьте в корзину две позиции: скидки быть не должно. Добавьте третью: самая дешёвая должна стать подарком.

2

Проверьте кратность

Если repeat: true, при шести товарах должно появиться два подарка. При false — один.

3

Проверьте промокод

Примените промокод: скидка акции должна исчезнуть. Удалите его: скидка должна вернуться.

Нюансы и диагностика

СитуацияЧто проверить
Акция не включаетсяКорзина открыта, каталог загрузился, товары имеют положительное количество; при фильтре списка UID добавлены верные UID.
Неверно определяется товар со скидкойСкрипт считает товар уценённым, если в каталоге указан priceold. Проверьте именно это поле у товара или вариации.
В корзине уже есть sale-товарПри ALLOW_SALE_ITEMS_DEFAULT: false стратегия minusOne уменьшает учитываемое количество на одну единицу; block блокирует выдачу полностью.
Что передаётся в заказПоле textarea[name="all_sales"] получает список подарков, процент и итоговую скидку; оно скрыто стилем в начале исходного кода.
Нужно увидеть причинуОставьте DEBUG: true и откройте консоль браузера: сообщения [CFREE] покажут товары, правила и выбранные единицы.
Инструкция создана по переданному скрипту. Для рабочего сайта измените ID категории и параметры акции, затем обязательно проверьте сценарии в опубликованной корзине Tilda.
Акция N = N − 1Инструкция к скрипту «самый дешёвый товар в подарок» для корзины Tilda
Доступ к материалу

Установка и настройка акции «3 по цене 2» в Tilda

Инструкция построена строго по вашему коду. Скрипт загружает каталог, следит за открытием корзины, выбирает самые дешёвые единицы и применяет к ним скидку — с учётом промокода и товаров с обычной скидкой.

Материалы

Что именно нужно вставить на сайт

Используйте переданный исходный блок целиком: в нём есть и CSS для бейджей/скрытого поля, и JavaScript. Внутри кода меняются только параметры в разделе «НАСТРОЙКИ» и массив DEALS.

Блок для установки

Скопируйте весь исходный фрагмент, начиная со <style> и заканчивая </script>. Не удаляйте служебные функции. Ниже показана только структура блока, а не готовый код для вставки.

<style>
  .cfree-badge { /* бейдж подарка */ }
  .cfree-strike { /* зачёркнутая цена */ }
  .t-input-group_ta[data-field-name="all_sales"] { display:none!important; }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
  (function () {
    // настройки и логика акции
  })();
});
</script>

Что делает исходный код

  • Загружает товары через API категории ALL_CATEGORY_ID.
  • Запускает пересчёт только при открытой корзине Tilda.
  • Считает отдельные единицы товара, поэтому две штуки одного товара учитываются по отдельности.
  • Даёт скидку самым дешёвым разрешённым единицам.
  • Показывает бейджи, меняет итоги и записывает сведения в all_sales.
Важно: эта версия не использует настройки targets, категорий товаров, CSV-вариаций или отключение проверок Tilda. Не добавляйте в неё шаги и параметры из старой инструкции — такого API в этом коде нет.
Шаг 1

Добавьте в корзину поле для информации об акции

01

Создайте поле all_sales

Откройте настройки корзины и раздел с полями. Нажмите «Добавить поле для ввода», выберите «Поле для ввода в несколько строк», установите количество строк 10 и задайте имя переменной all_sales. Сохраните настройки корзины.

Зачем это нужно: функция updateSalesTextarea() записывает сюда подарочные товары, размер скидки и её общий итог. В начале исходного кода это поле скрыто правилом .t-input-group_ta[data-field-name="all_sales"], поэтому покупатель его не увидит.
Шаг 3

Разместите исходный блок

03

Вставьте код в настройки сайта Tilda

После настройки ID категории скопируйте весь исходный блок. В Tilda откройте «Настройки сайта → Ещё → Редактировать код» и вставьте его в код проекта. Вставляется блок целиком — и <style>, и <script>. Такой способ подходит скрипту: он сам ждёт событие DOMContentLoaded, прежде чем обратиться к корзине и каталогу.

Не разбивайте блок: стили cfree-* и скрипт нужны вместе. Сохраните изменения и нажмите «Опубликовать все страницы».
Шаг 2

Укажите ID категории каталога

Каталог загружается запросом Tilda API. ID нужен для поиска названий товаров и определения позиции с уже заданной старой ценой.

02

Замените демонстрационный ID

В начале скрипта найдите ALL_CATEGORY_ID и поставьте ID нужной категории. Обычно используется служебная категория «Все товары». Если на странице уже объявлена переменная window.id_all_category_p, скрипт возьмёт её значение автоматически.

const ALL_CATEGORY_ID = String(
  window.id_all_category_p || '434145928791'
);
Проверка: при DEBUG = true после открытия корзины не должно быть сообщения Catalog: ошибка загрузки в консоли браузера.
Шаг 3

Настройте формат акции

Правило описывается так: buy — сколько единиц нужно взять, pay — сколько из них оплачивается. Разница получает скидку. Базовый вариант в вашем коде — один подарок при трёх товарах.

03

Выберите один из реальных вариантов DEALS

3 = 2, один разТри товара дают один подарок; шесть всё равно дают один.
3 = 2, повторяетсяПри шести товарах — два подарка, при девяти — три.
Скидка вместо подаркаНапример, 50% на самый дешёвый товар по правилу.
// 3 = 2: один подарок, правило не повторяется
const DEALS = [{ buy: 3, pay: 2, repeat: false, percent: 100 }];

// 3 = 2: повторяется на каждой кратности
const DEALS = [{ buy: 3, pay: 2, repeat: true, percent: 100 }];

// 4 = 3: скидка 50% на самую дешёвую единицу
const DEALS = [{ buy: 4, pay: 3, repeat: false, percent: 50 }];

exclusive: true — необязательный флаг. Если он стоит у правила, код игнорирует все остальные правила из массива и оставляет только первое такое правило.

Шаг 4

Определите товары, скидки и промокоды

04

На все товары или только по списку UID

По умолчанию USE_ALLOWED_LIST_DEFAULT = false, и акция применяется ко всем товарам. Чтобы ограничить её, включите фильтр и перечислите UID товара или UID его вариации в FREEBIE_ALLOWED_UIDS.

const USE_ALLOWED_LIST_DEFAULT = true;
const FREEBIE_ALLOWED_UIDS = [
  579586095852,
  640781596522
];
Важно: при true и пустом массиве ни один товар не участвует в акции. В этой реализации список — только UID; настройка по категориям отсутствует.
05

Как код обращается с товарами по старой цене

Товар считается уже уценённым, если у него или его вариации в каталоге есть priceold. При ALLOW_SALE_ITEMS_DEFAULT = false такой товар не может стать подарком. Дополнительно политика minusOne уменьшает количество, участвующее в расчёте, на одну единицу; block полностью блокирует выдачу подарка.

const ALLOW_SALE_ITEMS_DEFAULT = false;
const SALE_FREEBIE_POLICY = 'minusOne'; // или 'block'
06

Промокод имеет приоритет

Если в tcart.promocode есть успешный статус, сумма или процент скидки, скрипт снимает только собственную скидку акции, метки и запись в all_sales. Он не останавливается: после удаления промокода пересчёт автоматически вернёт акцию.

Шаг 5

Опубликуйте и проверьте корзину

Пересчёт работает, когда корзина открыта. Скрипт распознаёт стандартные состояния корзины Tilda: боковую панель, окно и страницу корзины.

01 · Порог

Добавьте две единицы — скидки нет. Добавьте третью — самая дешёвая разрешённая единица получает скидку.

02 · Кратность

При repeat: true шесть единиц дают два подарка. При false — только один.

03 · Промокод

Примените промокод: акция исчезает. Удалите промокод: скидка снова появляется.

Диагностика: пока тестируете, оставьте DEBUG = true. Сообщения с префиксом [CFREE] покажут состав корзины, рассчитанные правила, выбранные позиции и причины, по которым скидка не выдана.
Скриншоты из инструкции

Ориентиры в интерфейсе Tilda

Эти иллюстрации из переданной инструкции помогают найти нужные настройки без лишних поисков.

Настройка полей корзины Tilda
Настройки полей корзины
Добавление многострочного поля
Добавление многострочного поля
Карточка товара Tilda
UID обычного товара в карточке
Выгрузка CSV из каталога
Выгрузка списка товаров в CSV
Полная карта настроек

Все параметры, которые есть в исходном коде

Значения ниже соответствуют именно переданному JavaScript. Остальные функции менять не требуется.

ПараметрЗначение по умолчаниюРеальное действие
ENABLED_DEFAULTtrueСтартовое состояние акции. Если false, пересчёт не делает ничего до команды CFREE.enable().
DEBUGtrueВключает сообщения [CFREE] в консоли. На расчёт не влияет.
POLL_MS250Интервал пересчёта в миллисекундах, пока корзина открыта.
ALL_CATEGORY_IDдемо-IDID категории для загрузки каталога партиями по 500 товаров.
FREEBIE_DISCOUNT_PERCENT_DEFAULT100Резервный процент, если у конкретного правила DEALS не указан percent.
ALLOW_SALE_ITEMS_DEFAULTfalseРазрешает или запрещает отдавать товар со старой ценой priceold в качестве подарка.
SALE_FREEBIE_POLICY'minusOne'При наличии sale-товара: уменьшает учёт на одну единицу или полностью блокирует акцию при 'block'.
USE_ALLOWED_LIST_DEFAULTfalseВключает фильтр по FREEBIE_ALLOWED_UIDS.
Как работает код

Полная последовательность расчёта

A

Запуск, каталог и состояние корзины

После DOMContentLoaded код загружает каталог методом loadCatalog(). Он рекурсивно получает все страницы API, пока Tilda возвращает nextslice. MutationObserver следит за классами t706__body_cartsidebarshowed, t706__body_cartwinshowed и t706__body_cartpageshowed. При открытии запускается интервал, при закрытии он останавливается и бейджи очищаются.

B

Безопасный пересчёт

safeRecalc() сначала проверяет, включена ли акция, существует ли window.tcart и является ли tcart.products массивом. Затем проверяет промокод. Только после этого вызывает applyCheapestFree(); ошибки внутри него не останавливают работу страницы, а пишутся в консоль при включённом DEBUG.

C

Отбор единиц товара

Строки корзины с нулевым количеством отбрасываются. Если каталог не загружен или после UID-фильтра не осталось товаров, собственная скидка снимается. Количество каждой строки разворачивается в отдельные единицы: товар с количеством 3 становится тремя кандидатами с одинаковой ценой.

D

Выдача скидки

Правила сначала очищаются функцией sanitizeDeals(): остаются только правила, где buy > pay. calcFreebieAwards() создаёт список процентов скидки. Кандидаты сортируются по цене, затем по UID и индексу строки; первые N единиц получают скидку. Поэтому при равной цене выбор стабилен.

E

Итоги и интерфейс

liftOwnDiscount() вычитает предыдущую скидку скрипта из общей, сохраняет чужие скидки, пересчитывает tcart.prodamount_discountsum, prodamount_withdiscount и amount с доставкой. Затем код вызывает стандартный tcart__reDrawTotal(), добавляет бейджи и обновляет запасной вывод итогов.

Корзина и заказ

Что покупатель видит, а что получает заказ

Бейджи и сумма

  • Для полностью бесплатной позиции с 100% скидкой зачёркивается цена.
  • Бейдж показывает количество подарочных единиц или процент скидки.
  • Под итогом появляется строка с количеством, процентом и суммой скидки.
  • Если для разных подарков заданы разные проценты, интерфейс показывает их через «/».

Скрытое поле заказа

Функция updateSalesTextarea() ищет textarea[name="all_sales"]. В него записываются название товара, количество, скидка по каждой позиции и общий итог. Стиль в начале кода скрывает это поле на странице.

Название: сначала ищется товар по UID в загруженном каталоге; для вариации код соединяет название основного товара и название вариации. Если товар не найден, в заказ попадёт «UID …».
Команды консоли

Публичный объект window.CFREE

Эти команды уже создаёт ваш код. Они полезны для проверки без редактирования исходника.

КомандаДействие
CFREE.enable()Включает акцию и запускает немедленный пересчёт.
CFREE.disable()Снимает собственную скидку, бейджи, итоговую строку и очищает all_sales.
CFREE.recalcNow()Выполняет один безопасный пересчёт прямо сейчас.
CFREE.useAllowedList() / CFREE.useAllProducts()Включает UID-фильтр или возвращает участие всех товаров.
CFREE.setAllowedFilter(true|false)То же переключение фильтра с аргументом.
CFREE.allowSaleItems() / CFREE.disallowSaleItems()Меняет в памяти страницы отношение к товарам с priceold.
CFREE.setFreebieDiscountPercent(50)Задаёт резервный процент 0–100 с ограничением значения.
CFREE.getAllowedFilterState(), getSaleItemsState(), getFreebieDiscountPercent()Возвращают текущие значения настроек.
CFREE.clearDebugLogCache()Очищает кэш повторяющихся отладочных сообщений.
Почему команды не меняют код навсегда

Команды меняют переменные в текущей вкладке. После обновления страницы снова применяются значения из исходного блока: ENABLED_DEFAULT, USE_ALLOWED_LIST_DEFAULT, ALLOW_SALE_ITEMS_DEFAULT и другие.

Короткая памятка по настройке

Меняйте только ID категории, массив DEALS, фильтр UID и параметры скидок. Остальная часть кода отвечает за загрузку каталога, перерасчёт сумм и интерфейс корзины.

Акция 3 по цене 2Пошаговая установка скрипта для корзины Tilda
Инструкция по установке

Каждый шаг — действие и скриншот

Настройки и примеры ниже соответствуют переданному коду акции «самый дешёвый товар в подарок».

1. Настройка корзины

Создайте поле для информации об акции в заказе.

01

Добавьте поле all_sales

  1. Откройте настройки корзины и её поля.
  2. Нажмите «Добавить поле для ввода».
  3. Выберите «Поле для ввода в несколько строк».
  4. Укажите 10 строк и имя переменной all_sales.
  5. Нажмите «Сохранить и закрыть».
Почему это нужно: updateSalesTextarea() записывает сюда подарки, размер скидки и итог. CSS в предоставленном блоке скрывает поле от покупателя.
Поля корзины Tilda
Настройки полей корзины

2. Найдите ID категории «Все товары»

Этот ID необходим коду, чтобы загрузить каталог товаров.

02

Найдите data-storepart-uid

  1. Создайте временную пустую страницу и добавьте блок каталога, например ST310N.
  2. Удалите товары по умолчанию и выберите «Все товары из каталога».
  3. Опубликуйте страницу, наведите на «Все» и выберите «Исследовать» / «Просмотреть код».
  4. Найдите атрибут data-storepart-uid. Его число — ID категории.
const ALL_CATEGORY_ID = String(window.id_all_category_p || 'ВАШ_ID_КАТЕГОРИИ_ВСЕ');
Важно: в этом коде настраивается ALL_CATEGORY_ID. Переменная window.id_all_category_p используется только как резервное значение.
Вывод товаров Tilda
Временная страница с выводом товаров каталога

3. Задайте правило акции

В массиве DEALS укажите, сколько товаров нужно взять и сколько оплатить.

03

Настройте DEALS

buy — количество единиц в акции, pay — количество оплачиваемых, percent — скидка на самые дешёвые единицы.

const DEALS = [{ buy: 3, pay: 2, repeat: false, percent: 100 }];
Повторяемая акция: поставьте repeat: true, если при 6 товарах должно быть 2 подарка. Для скидки 50% замените percent: 100 на percent: 50.
Редактирование кода Tilda
Изменяйте только параметры в начале кода

4. Ограничьте акцию товарами при необходимости

По умолчанию акция действует на все товары. Этот шаг нужен только для ограниченного списка.

04

Добавьте UID товаров или вариаций

  1. UID обычного товара указан внизу его карточки в каталоге.
  2. Для вариаций выберите в каталоге «Скачать список товаров в CSV».
  3. Откройте CSV в Excel: кодировка UTF-8, разделитель «точка с запятой».
  4. UID вариаций находятся в первом столбце.
const USE_ALLOWED_LIST_DEFAULT = true; const FREEBIE_ALLOWED_UIDS = [579586095852, 640781596522];
Важно: используйте FREEBIE_ALLOWED_UIDS, а не my_name_tovar1 из старой инструкции. UID товара и вариации поддерживаются. Пустой список при включённом фильтре отключает акцию.
Скачать список товаров в CSV
Выгрузка списка товаров и вариаций в CSV

5. Разместите код и проверьте результат

Вставляется весь предоставленный блок со стилями и JavaScript.

05

Опубликуйте сайт и проверьте корзину

  1. Откройте «Настройки сайта → Ещё → Редактировать код».
  2. Вставьте исходный блок целиком: от <style> до </script>.
  3. Сохраните и нажмите «Опубликовать все страницы».
  4. Откройте магазин в инкогнито: два товара не дают скидку, третий даёт скидку на самый дешёвый.
  5. Проверьте промокод: при нём собственная скидка акции снимается, а после удаления возвращается.
Ошибка стоимости: если Tilda сообщает о несоответствии суммы или скидки, откройте «Настройки сайта → Платёжные системы → Общие настройки → Настроить» и установите «Уровень проверки скидки» — «Не проверять».
Публикация сайта Tilda
После изменений опубликуйте все страницы

Акция готова к запуску

Для диагностики оставьте DEBUG = true: сообщения [CFREE] в консоли покажут расчёт и причину, если скидка не выдана.

Вернуться к шагу 1