Common changes
Step-by-step recipes for the changes this repository needs most often, and the files that have to change together.
Add a new section
- Create
sections/<name>.liquid. - Write the schema with settings for everything a merchant might want to change, including wording, images, links,
thresholds and an enable toggle. Keep these values in the schema, not hardcoded in the markup.
AGENTS.mdmakes this a project requirement. - Wrap the content in two elements. The outer one carries the background so it can run full width, and the inner one
limits the content width. Existing sections name the wrappers after the section, for example
shop-by-routine--outer-wrapperandshop-by-routine--inner-wrapper, and set the outer name as the schema'sclass. - Size the inner wrapper with
calc(100% - var(--gutter))and add--gutteras a schema setting. - Add a
presetsblock so staff can add the section from the theme editor. - If the section needs JavaScript or its own CSS, add an entrypoint as described below.
- Run
npm run lint:fix, then read the remaining output.
No section in the theme uses --gutter yet, and only a few follow the wrapper convention. The convention is for new
work. You do not have to convert an old section when you touch it, but do not copy an old section's structure into a new
one.
Add a new entrypoint
- Create the file anywhere under
src/entrypoints. The build finds it automatically, and there is no list to update. - Build once so
snippets/vite-tag.liquidregenerates. Runnpm run build, or keepnpm run devrunning. - Render it from Liquid with the path relative to
src/entrypoints:
{%- render 'vite-tag' with 'my-feature.ts' -%}
{%- render 'vite-tag' with 'my-feature.css', preload_stylesheet: true -%}- Regenerate the entrypoint table:
python3 doc-site/scripts/build-entrypoint-table.pyIf the path matches no branch of the generated snippet, the render outputs nothing and reports no error. When a script does not run, check the path first.
Add a mini-cart element
Copy src/entrypoints/mini-cart/elements/00-example.ts. It is a template for new elements. It shows a custom element
that creates an AbortController when connected, subscribes to the bus, renders from the cart it receives, and aborts
when disconnected.
These files change together:
| Change | File |
|---|---|
| The element itself | src/entrypoints/mini-cart/elements/<name>.ts |
| Its styles | src/entrypoints/mini-cart/elements/<name>.css |
Its markup and the vite-tag renders | snippets/mini-cart.<name>.liquid |
| A block definition with a render location | sections/mini-cart.liquid |
| Dispatch by render location | snippets/mini-cart.render-blocks.liquid |
Never change the cart directly from an element. Dispatch a command event, or use SimpleCartService for changes
addressed by line, so the change gets its stale-key recovery.
Add a cart event
- Add the name to
CartEventsinsrc/entrypoints/mini-cart/internals/core.ts. - Add its payload type to
CartEventDetailMapin the same file. - Emit it with
CartEventBus.emitinstead of constructing aCustomEventby hand, so every payload gets theexternalflag. - Document it in Cart events.
Add a value that Liquid passes to JavaScript
- Decide where it belongs. A single value for one component goes on a
data-attribute. Structured data goes in a JSON script tag. Only store-wide values go onwindow.theme. - When you add to
window.theme, create the key only if it is missing, as inwindow.theme.x = window.theme.x || {}. Snippets run in no fixed order. - Output the value with
| jsoninstead of wrapping it in quotes, so an apostrophe in a merchant's text cannot break the script. - Add the property to
src/@types/global.tsin the same commit. Mark it optional if only some pages render it. - If the value is store-wide, check whether the other two layouts need the same change.
Add a theme setting
- Add it to the right group in
config/settings_schema.json, or create a group. - Use a valid setting type.
config/settings_schema.jsonalready contains one invalid type that Theme Check reports, so check any neighbouring setting before you copy it. - Read it in Liquid as
settings.<id>. - Run
npm run lint:fixand confirm the schema still validates. - Record it in Theme settings.
The theme editor writes setting values to config/settings_data.json. Do not edit that file by hand, because the next
theme pull overwrites it.
Change something that a metafield drives
Metafields are Shopify data, not theme code. The theme reads them and must work when they are absent.
Read a metafield with an explicit fallback chain, as snippets/medispa-calendar-config.liquid does. It uses the
product's own value first, then the page override, then the theme setting, then a literal default. For a boolean that
can be false on purpose, test the metafield's type instead of its value. Liquid's default filter treats false as
absent unless you pass allow_false: true.
A new metafield also needs a definition in Shopify admin, which this repository does not hold. Record it in Metafields and metaobjects.
Before you open a pull request
npm run typecheck
npm run build
npm run lint
npm run format:check
git statusIn the git status output, check that snippets/vite-tag.liquid holds built asset names, not localhost:5173 URLs. If
you changed Tailwind classes, check that src/entrypoints/theme.styles.css was rebuilt.
See Conventions for what reviewers look for.