Когда клиент просит собрать на Tilda не лендинг с десятком карточек, а полноценный динамический каталог товаров на Tilda с сотнями позиций, фильтрами и синхронизацией с 1С или Google Таблицами, стандартный редактор блоков перестаёт справляться уже на второй сотне товаров. Я собирал такие каталоги и на встроенном Tilda Store, и на Zero Block с внешним JSON-фидом, и на связке с CRM через n8n - расскажу, что происходит внутри каждого варианта, где Tilda реально упирается в потолок, а где потолок снимается кастомным скриптом.
Из чего вообще состоит каталог на Tilda
Под капотом у Tilda нет единого «движка каталога» - есть три разных механизма, которые внешне выглядят одинаково, но работают по-разному.
Первый - встроенный T‑Store: товары хранятся в базе Tilda, редактируются в панели «Магазин», а на странице подгружаются скриптом с домена store.tildacdn.info. Второй - Zero Block с динамическими записями: карточки собираются на лету из JSON, который может лежать где угодно - на вашем сервере, в Google Таблице, в выгрузке из 1С. Третий - гибрид: тот же T‑Store, но поверх накручен собственный JS, который добавляет фильтры, сортировку или синхронизацию остатков, которых в редакторе просто нет.
| Способ | Где хранятся товары | Практический предел | Фильтры | Когда брать |
|---|---|---|---|---|
| T‑Store | база Tilda, отдаётся через store.tildacdn.info | рендер начинает подвисать уже на 200-300 карточках на странице | готовые чекбоксы/радио по атрибутам | магазин до пары сотен SKU без внешней синхронизации |
| Zero Block + свой JSON-фид | внешний источник: Sheets API, выгрузка 1С, CRM | упирается в браузер клиента, а не в Tilda | пишете сами на JS | каталог с автообновлением цен и остатков |
| Гибрид T‑Store + кастомный JS | база Tilda + своя обвязка | те же ограничения Store | расширенные фильтры и быстрый просмотр | нужно докрутить существующий магазин без переезда |
Как Tilda Store хранит и отдаёт товары под капотом
При открытии страницы с блоком T‑Store браузер делает отдельный запрос к API Tilda, получает список товаров в JSON и складывает его в глобальный объект window.tstore. Дальше уже клиентский скрипт Tilda рендерит карточки, вешает обработчики на кнопку «Купить» и следит за фильтрами через классы вида t‑store__filter и data-tilda атрибуты на блоках категорий.
Проблема в том, что весь список товаров грузится одним куском при заходе на страницу - категорий и постраничной подгрузки на уровне API нет, есть только скрытие/показ карточек через CSS. Поэтому каталог на 500+ позиций в T‑Store не «не работает», а начинает заметно тормозить на слабых телефонах: браузер держит в DOM сотни скрытых карточек одновременно. Я на практике встречал магазины, где страница каталога весила 4-5 МБ только за счёт этого JSON и картинок без ленивой загрузки.
Отдельная головная боль - синхронизация остатков. T‑Store меняется только руками в редакторе или через официальный Tilda API (ограниченный набор эндпоинтов для создания/обновления товаров), без вебхуков на изменение цены. Если нужно тянуть остатки из 1С каждую ночь, приходится городить скрипт, который дергает Tilda API по расписанию - либо вообще уходить на Zero Block с собственным фидом.
Zero Block и динамические страницы: рендер карточки на лету
Zero Block даёт доступ к HTML/CSS/JS блока напрямую, и это открывает путь к настоящему динамическому каталогу: вместо готовых карточек Tilda на странице лежит пустой контейнер, а JS сам запрашивает данные и рисует разметку.
Схема на практике простая: делаете Google Таблицу с товарами, публикуете её через Google Apps Script как JSON-эндпоинт (или используете отдельный бэкенд), а в Zero Block вставляете скрипт, который тянет фид и рендерит карточки.
fetch('https://script.google.com/macros/s/XXXX/exec')
.then(res => res.json())
.then(items => {
const wrap = document.querySelector('#catalog-grid');
wrap.innerHTML = items.map(item => `
<div class="catalog-card" data-price="${item.price}" data-category="${item.category}">
<img src="${item.image}" loading="lazy" alt="${item.title}">
<h3>${item.title}</h3>
<span>${item.price} ₽</span>
</div>
`).join('');
});
Плюс такого подхода - полный контроль над версткой, скоростью загрузки и логикой фильтров. Минус - всё, что T‑Store делает из коробки (корзина, оформление заказа, интеграция с эквайрингом), приходится собирать руками или подключать сторонний сервис корзины поверх.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Подключение внешних источников: 1С, CRM и Google Таблицы
Самый частый запрос - «чтобы цены на сайте менялись сами, когда меняются в 1С». Реализация зависит от того, что уже есть у клиента.
Если 1С выгружает данные в формате CommerceML, я обычно ставлю промежуточный скрипт на сервере, который раз в сутки конвертирует выгрузку в плоский JSON и отдаёт его по адресу, который читает Zero Block. Если проще - использую n8n: сценарий по расписанию забирает данные из CRM или Google Таблицы, приводит к нужному формату и кладёт в облачное хранилище или базу, откуда каталог их читает. Это снимает нагрузку с самой Tilda и не зависит от лимитов её API.
Отдельно стоит связка с Telegram: под менеджера склада я собирал aiogram-бота, который присылает уведомление, если товар на сайте закончился, и в один клик снимает его с публикации через тот же скрипт синхронизации - без захода в 1С или в редактор Tilda.
Готовые куски такого рода скриптов - синхронизация остатков, конвертация фида, разбор CommerceML - я собираю в библиотеке готовых скриптов для Tilda, там же можно смотреть, как устроена конкретная интеграция, прежде чем заказывать доработку под свой случай.
Фильтры и сортировка без перезагрузки страницы
В T‑Store фильтры завязаны на атрибуты товара, заданные в редакторе, и работают через показ/скрытие карточек - без похода на сервер. В кастомном каталоге на Zero Block логика та же, просто пишете её сами: вешаете data-атрибуты на карточку при рендере и переключаете видимость по клику на кнопку фильтра.
document.querySelectorAll('[data-filter]').forEach(btn => {
btn.addEventListener('click', () => {
const cat = btn.dataset.filter;
document.querySelectorAll('.catalog-card').forEach(card => {
const match = cat === 'all' || card.dataset.category === cat;
card.style.display = match ? '' : 'none';
});
});
});
document.querySelector('#sort-price').addEventListener('change', e => {
const grid = document.querySelector('#catalog-grid');
const cards = [...grid.children].sort((a, b) =>
e.target.value === 'asc'
? a.dataset.price - b.dataset.price
: b.dataset.price - a.dataset.price
);
cards.forEach(card => grid.appendChild(card));
});
На комбинированных фильтрах (категория + цена + наличие одновременно) я обычно завожу один общий объект состояния фильтров и одну функцию applyFilters, которая пробегает по всем карточкам и проверяет сразу все условия - так проще не запутаться, когда фильтров становится пять-шесть, а не два.
Оплата и доставка внутри карточки товара
Эквайринг в T‑Store подключается через настройки платежных систем в панели - Т‑Банк, ЮKassa и другие поддерживаются нативно, без своего кода. В кастомном каталоге на Zero Block такой кнопки нет по умолчанию: при оформлении заказа приходится либо дергать API Т‑Банка напрямую для создания платежа и получения ссылки на оплату, либо встраивать готовый виджет оплаты поверх своей корзины.
С доставкой похожая история. Расчет стоимости СДЭК я обычно завожу через собственный запрос к API СДЭК прямо из карточки товара или корзины: пользователь вводит город, скрипт кэширует результат в localStorage на несколько часов (тарифы СДЭК не меняются поминутно) и подставляет стоимость доставки в итоговую сумму заказа без перезагрузки страницы. Для комплексных интеграций с оплатой и доставкой, где нужно свести CRM, эквайринг и расчет доставки в одном сценарии, обычно требуется отдельная доработка - я такие делаю как кастомизацию Tilda под конкретный магазин, простая правка стоит от 3 000 ₽, комплексная интеграция с CRM, эквайрингом и СДЭК - от 40 000 ₽.
Производительность каталога: пагинация, ленивая подгрузка и кэш
Самая частая причина медленного каталога - не сама Tilda, а то, как собран фид и разметка. На практике вытягиваю скорость тремя вещами.
- Пагинация чанками по 24-36 карточек вместо рендера всего списка сразу - остальное подгружается при скролле через IntersectionObserver.
- Ленивая загрузка изображений через атрибут loading=“lazy” и сжатие картинок в WebP - на каталоге из 300 товаров это обычно режет вес страницы вдвое.
- Кэширование JSON-фида в localStorage с временем жизни 10-15 минут - повторные заходы на страницу не гоняют полный запрос к Google Таблице или 1С каждый раз.
Если каталог собран на Zero Block с внешним фидом, полезно ещё разнести раздачу JSON и картинок через CDN - тогда даже при синхронизации с 1С раз в час фронтенд не чувствует нагрузку на бэкенд.
Когда стандартных блоков не хватает
Кастомный скрипт
от 3 000 ₽
Подробнее →Частые вопросы
Сколько товаров реально выдержит каталог на Tilda?
Встроенный T‑Store начинает заметно тормозить на слабых устройствах уже на 200-300 карточках на одной странице, потому что весь список рендерится в DOM сразу. Каталог на Zero Block с пагинацией и ленивой подгрузкой держит тысячи позиций без проблем - упирается не в Tilda, а в объём и качество самого фида.
Можно ли подключить 1С к каталогу на Tilda напрямую?
Напрямую - нет, у 1С и Tilda разные форматы данных и нет готового коннектора из коробки. На практике ставится промежуточный скрипт или сценарий в n8n, который конвертирует выгрузку 1С в JSON и отдаёт его каталогу по расписанию.
Чем динамический каталог отличается от обычного Tilda Store?
T‑Store - это готовый механизм с ограниченным набором функций и данными внутри Tilda. Динамический каталог на Zero Block берет данные из любого внешнего источника и рендерит карточки собственным скриптом, поэтому в нём можно реализовать любую логику фильтров, сортировки и синхронизации, которой нет в редакторе.
Нужен ли программист для доработки каталога на Tilda?
Для простых правок фильтра или сортировки хватает разбора существующего JS-кода блока. Для синхронизации с 1С, CRM, расчета доставки через СДЭК или подключения эквайринга напрямую через API обычно нужен отдельный скрипт - без него такие вещи в редакторе Tilda не собираются.