Стили, скрипты и картинки темы
Как подключать свои файлы, что магазин добавляет сам и почему порядок подключения важен.
На этой странице
Файлы оформления лежат в папке assets/ внутри темы и отдаются браузеру по
адресу /theme-assets/имя-темы/…. Этот адрес всегда доступен в шаблоне:
<img src="{$theme.assets}/img/logo.svg" alt="{$storefront.name}">
Файлы за пределами assets/ браузеру не отдаются. Шаблоны, манифест и
переводы через этот адрес не прочитать — это защита, а не недоработка.
Три файла, которые магазин просит всегда
На каждой странице магазин подключает три файла вашей темы:
assets/vendor/fontawesome/all.min.css
assets/css/theme.css
assets/js/theme.js
Их нет — страница не сломается, но в консоли браузера будет три ошибки 404. Заведите их сразу, хотя бы пустыми: набор значков вам, скорее всего, понадобится другой, но файл по этому пути магазин попросит в любом случае.
Подключение своих файлов
{block name="page_assets"}
{asset_css file="css/product.css"}
{asset_js file="js/product.js" defer=true}
{/block}
| Параметр | Что делает |
|---|---|
file |
путь внутри assets/ вашей темы |
inline |
вставить содержимое прямо в страницу, а не ссылкой |
key |
имя, по которому файл не подключится дважды |
head / footer |
куда выводить |
| остальные | уезжают атрибутами в <link> или <script> |
Всё, что не названо, становится атрибутом: defer=true, async=true,
media="print", type="module".
Один и тот же файл, подключённый дважды, выводится один раз. Если один и тот же
файл лежит под разными именами — задайте им общий key, и подключится только
первый.
Вывод собранного списка
{assets_head} в <head>
{assets_footer} перед </body>
⚠️ Порядок важен. Всё, что зарегистрировано после {assets_head}, в
шапку уже не попадёт. Поэтому блок page_assets в каркасе стоит до
{assets_head}:
{block name="page_assets"}{/block}
{assets_head}
В эти два места выводятся и ваши файлы, и те, что магазин подключает сам, и те, что добавляют дополнения. Без них витрина останется без оформления и без поведения.
Что магазин подключает сам
Тема этого не делает и не должна дублировать.
| Где | Что |
|---|---|
| везде | cart-sync.js — счётчик корзины и пометки «в корзине» |
| везде | search.css, search.js — живой поиск |
| страницы оформления | checkout.css, checkout.js |
| страница оплаты | pay.js |
| страницы товара | accessories.css, accessories.js — комплекты |
| страницы товара | packaging.css, packaging.js — счёт упаковками |
Свой checkout.css темы переопределять вид можно и нужно — он подключается
после магазинного. А вот свой скрипт оформления писать не стоит: см.
Атрибуты data-*.
Сторонние библиотеки — файлами, а не ссылкой
Слайдер, ползунок цены, набор значков кладутся в assets/vendor/ и подключаются
оттуда:
assets/vendor/
swiper/
nouislider/
fontawesome/
Почему не ссылкой на чужой сайт: внешний адрес — это чужая доступность, чужая скорость и чужие правила про данные покупателей. Упал внешний источник — у магазина рассыпалась вёрстка, и владелец не может ни починить, ни объяснить это покупателю. Плюс свой файл отдаётся с правильным типом и с длинным кэшем.
Единственное исключение — reCAPTCHA: её скрипт приходит с сайта Google, и это выбор владельца магазина, а не темы.
Кэш браузера: две ловушки
К каждому файлу, подключённому через {asset_css} и {asset_js}, магазин
дописывает метку версии — браузер всегда берёт свежий файл. Сами файлы при этом
отдаются с длинным кэшем: месяц и «не перепроверять».
Отсюда две ловушки, на которые наступают все.
Первая: страница пришла из кэша — в ней заморожена старая метка. Браузер честно держит старый файл месяц. Лечится сбросом страниц витрины и жёсткой перезагрузкой.
⚠️ Вторая, и она хуже: файл, подключённый вручную, метки не получает вовсе.
{* так делать нельзя — файл залипнет у покупателя на месяц *}
<link rel="stylesheet" href="{$theme.assets}/css/my.css">
{* так правильно *}
{asset_css file="css/my.css"}
Через {$theme.assets} подключают картинки и шрифты, а стили и скрипты —
только тегами.
Картинки
<img src="{$theme.assets}/img/no-photo.svg" alt="">
Картинки темы — это заглушки, значки, фон: то, что принадлежит оформлению.
Фотографии товаров приходят в данных и режутся тегом {thumb}:
<img src="{thumb src=$product.image size=320}" alt="{$product.name}">
Подгрузку картинок при прокрутке владелец включает настройкой темы — она
приходит в листинге как image_lazy:
<img src="{thumb src=$product.image size=320}"
{if $image_lazy}loading="lazy"{/if} alt="{$product.name}">
Шрифты
Кладутся в assets/ и подключаются из своего же CSS:
@font-face {
font-family: 'Inter';
src: url('../fonts/inter.woff2') format('woff2');
font-display: swap;
}
Пути внутри CSS считаются от самого файла стилей — {$theme.assets} там не
работает.
Шрифт можно сделать настройкой темы ("type": "font"), тогда владелец выбирает
его в панели, а тема читает выбор:
<style>:root { --font: {$theme.font_family}, system-ui, sans-serif; }</style>
Цвета настройками
Удобный приём: цвета из настроек темы выводятся переменными CSS в каркасе, а всё остальное оформление опирается на них.
<style>
:root {
--primary: {$theme.colors.primary|default:'#4f46e5'};
--accent: {$theme.colors.accent|default:'#f59e0b'};
--bg: {$theme.colors.bg|default:'#ffffff'};
--text: {$theme.colors.text|default:'#1f2937'};
--container: {$theme.container_width|default:1240}px;
}
</style>
Так владелец меняет вид магазина из панели, а вам не нужно ни пересобирать стили, ни держать по файлу на каждую цветовую схему.
Пустая папка не доедет до клиента
⚠️ В пакет темы складываются файлы. Папка без единого файла в архив не
попадёт: завели assets/css/ пустой — у клиента её не будет.
Что ещё не попадает в пакет и почему — на странице Упаковка и публикация.