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.
What can go in assets/
Section titled “What can go in assets/”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.
Liquid in assets isn’t rendered
Section titled “Liquid in assets isn’t rendered”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:
{%- style -%} :root { --page-width: {{ settings.page_width }}px; --radius: {{ settings.radius }}px; }{%- endstyle -%}Images merchants choose
Section titled “Images merchants choose”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?

