Components
Component Structure
A component is a folder inside components/ containing up to three files:
components/blocks/cart_summary/
index.liquid ← Liquid template (required)
index.js ← JavaScript class (optional)
style.scss ← Scoped styles (optional)The Liquid file is the only required file. JavaScript and styles are opt-in per component.
Connecting JS to HTML
Components are connected to their JavaScript via the data-component attribute:
<div data-component="blocks/cart_summary">
<!-- component markup -->
</div>The attribute value must match the path from the component type root (blocks/, sections/, parts/). The JS module system uses import.meta.glob to discover all components/**/*.js files and matches them by path.
WARNING
Do not use leading slashes. Use blocks/my_feature, not /blocks/my_feature.
JavaScript Class Pattern
Every component JS file exports a single default class:
export default class CartSummary {
constructor(element) {
this.element = element
this.init()
}
init = () => {
// Cache DOM elements, bind events
}
// Optional lifecycle methods:
load() // Called after instantiation (Page-level only, awaited)
resize() // Called on window resize via Page.triggerEvent
tick() // Called every frame via requestAnimationFrame (App-level)
}Rules
- Export a single default class
- Accept the DOM element as the constructor's first argument
- Use arrow function class fields for methods (ensures correct
thisbinding) - Import
appfrom the core module to access services — never use globals
Loading Contexts
Components are loaded in two contexts depending on their position in the DOM:
| Context | Selector | Manager | Purpose |
|---|---|---|---|
| App-level | [data-component] outside main#app | App.loadAppInstances() | Persistent chrome (header, overlays) |
| Page-level | [data-component] inside main#app | Page.createInstances() | Page content, destroyed on navigation |
App-level components persist across page navigations. Page-level components are created when the page loads and destroyed when the user navigates away.
Component Categories
Sections (components/sections/)
Full Shopify sections with {% schema %} blocks. These define configurable content areas in the Shopify theme editor.
Examples: header, footer, product, collection
Blocks (components/blocks/)
Reusable UI blocks rendered via {% render %}. These are the workhorses of the theme.
Examples: cart_summary, cart_item, pdp/gallery, pdp/info, layout/header/nav
Parts (components/parts/)
Small, reusable primitives.
Examples: buttons/primary, form/input, image, price, video_hls
Icons (components/icons/)
SVG icon partials. Each icon is a single .liquid file.
Globals (components/global/)
Cross-cutting Liquid files like head, javascript_variables, translation_strings.
Rendering Components
Use {% render %} with the flattened snippet name (dots instead of slashes):
{% render 'parts.button', label: 'Add to Cart', variant: 'primary' %}
{% render 'blocks.cart_summary' %}
{% render 'icons.search' %}TIP
Always pass data via named parameters. Never use {% include %} (deprecated).