Developer reference

Aurelia is plain Liquid, plain CSS, and plain JavaScript. There is no build step, no bundler, no framework, and no dependency to install. shopify theme dev serves the files exactly as they sit on disk.


Layout of the theme

assets/       critical.css + one CSS/JS file per section and component
blocks/       group, text, custom-liquid — nestable inside Custom section
config/       settings_schema.json (theme settings), settings_data.json (the three styles)
docs/         this documentation; excluded from theme push by .shopifyignore
layout/       theme.liquid, password.liquid
locales/      en.default.json (storefront), en.default.schema.json (editor labels)
sections/     27 addable sections + 25 template sections + the two section groups
snippets/     product-card, breadcrumbs, structured-data, meta-tags, wishlist, …
templates/    JSON templates, plus gift_card.liquid

How CSS and JS load

Aurelia deliberately does not use {% stylesheet %} and {% javascript %}. Shopify concatenates those tags across the whole theme into a single bundle that is served on every page — so a rule written for the ring sizer would ship on the checkout-less 404 page too. Instead:

```

A page therefore carries the CSS and JS of the sections actually on it and nothing else. The homepage lands around 93 KB of CSS and JS, the product page around 98 KB, the collection page around 80 KB — each figure including the shared 28 KB of critical.css.

Two rules when you add a section

  1. Guard your script. A section can appear more than once on a page, and a duplicate <script src> executes again (a duplicate <link> does not). Every JS asset opens with a run-once flag: js if (!window.__aureliaSectionHero) { window.__aureliaSectionHero = true; // … }
  2. Never put Liquid in an asset file. assets/*.js and assets/*.css are static — Liquid is not evaluated there, so {{ 'foo' | t }} ships as literal text. Pass translated strings and merchant settings through data-* attributes on the markup instead, the way snippets/wishlist.liquid carries its announcement strings on a hidden <span>.

Colour

Three tokens are set in snippets/css-variables.liquid and everything else is derived from them:

Token Source
--color-background theme setting, or the section's colour scheme
--color-foreground theme setting, or the section's colour scheme
--color-accent theme setting, or the section's colour scheme
--color-muted color-mix(…foreground 70%, background)
--color-border color-mix(…foreground 14%, background)
--color-on-media fixed #FDFCFA, for text over images

--color-muted carries real body text — placeholders, unit prices, policy links, captions — so the 70% mix is a contrast floor, not a taste decision. Below roughly 68% it drops under 4.5:1 on the warmer palettes. If you add a palette, check the muted colour against its background before shipping it.

Section colour schemes come from settings_data.json. Each of the three presets (Ivory, Noir, Champagne) defines its own color_schemes block, so switching style changes the schemes too rather than leaving a dark band from the previous palette.

Shared JavaScript

Five globals, all reachable on every page because the layout renders their sections and snippets outside content_for_layout:

Global Defined in Does
AureliaAnnounce(text) snippets/live-region.liquid Speaks a message through the page's role="status" region — cart changes, wishlist saves, filter results
AureliaCart assets/section-cart-drawer.js open, add, change, refresh; every add-to-cart on the storefront goes through it
AureliaWishlist assets/component-wishlist.js toggle, all, sync; persists to localStorage, keeps aria-pressed in step
AureliaMotion assets/motion-toggle.js Pause/play for anything that animates on its own; fires aurelia:motion
AureliaQuickView assets/component-quick-view-modal.js Fetches a product form through the Section Rendering API and opens it in a <dialog>

Section Rendering API

Two places fetch markup rather than rendering it inline:

Accessibility conventions

Checks before you commit

shopify theme check

.theme-check.yml runs theme-check:all, not the recommended subset. The one documented exception is AssetSizeJavaScript on templates/gift_card.liquid: qr-code.js is 14 KB uncompressed but 4.5 KB over the wire, it is the theme's own generator rather than a vendored library, and it loads on the gift-card page alone. Every other template is held to the rule. A clean run reports zero offenses — keep it that way rather than widening the ignore list.