Skip to content

Assets

Files in assets/ are served from the store’s own domain:

{{ 'base.css' | asset_url | stylesheet_tag }}
<script src="{{ 'theme.js' | asset_url }}" defer></script>
<img src="{{ 'logo.svg' | asset_url }}" alt="{{ shop.name }}" width="120" height="32">

asset_url gives /cdn/shop/t/<theme-id>/assets/base.css?v=<hash>. The hash changes when the file changes, so browsers keep each version for a year and fetch the new one at once after a save.

CSS, JavaScript, JSON, SVG, text, images (PNG, JPEG, WebP, AVIF, GIF, ICO), fonts (WOFF2, WOFF, TTF, OTF), MP4 and WebM video, and PDF, up to 20 MB each. Text files are created in the code editor; images, fonts and media are uploaded with Upload asset. Uploaded SVGs are cleaned of scripts.

assets/theme.css.liquid is served as it is. CSS that depends on settings goes in a {% style %} tag in a snippet or section, as Sahil’s snippets/css-variables.liquid does:

snippets/css-variables.liquid
{%- style -%}
:root { --page-width: {{ settings.page_width }}px; --radius: {{ settings.radius }}px; }
{%- endstyle -%}

Logos, banners and other images merchants pick come from image_picker settings, not from assets/. Pass them to image_url to get resized WebP copies from the image CDN.

Ship font files in assets/ and declare them with @font-face (see Fonts). Preload the one or two files the first screen needs:

<link rel="preload" href="{{ 'geist-latin-wght-normal.woff2' | asset_url }}" as="font" type="font/woff2" crossorigin>

Was this page helpful?