Документація

Стилі, скрипти та зображення теми

Як підключати власні файли, що магазин додає сам і чому порядок підключення важливий.

На цій сторінці

Файли оформлення лежать у теці 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/ порожньою — у клієнта її не буде.

Що ще не потрапляє в пакет і чому — на сторінці Пакування і публікація.

Оновлено 24 серпня 2026