Beauty Affairs HK

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

  1. Create sections/<name>.liquid.
  2. 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.md makes this a project requirement.
  3. 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-wrapper and shop-by-routine--inner-wrapper, and set the outer name as the schema's class.
  4. Size the inner wrapper with calc(100% - var(--gutter)) and add --gutter as a schema setting.
  5. Add a presets block so staff can add the section from the theme editor.
  6. If the section needs JavaScript or its own CSS, add an entrypoint as described below.
  7. 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

  1. Create the file anywhere under src/entrypoints. The build finds it automatically, and there is no list to update.
  2. Build once so snippets/vite-tag.liquid regenerates. Run npm run build, or keep npm run dev running.
  3. 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 -%}
  1. Regenerate the entrypoint table:
python3 doc-site/scripts/build-entrypoint-table.py

If 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:

ChangeFile
The element itselfsrc/entrypoints/mini-cart/elements/<name>.ts
Its stylessrc/entrypoints/mini-cart/elements/<name>.css
Its markup and the vite-tag renderssnippets/mini-cart.<name>.liquid
A block definition with a render locationsections/mini-cart.liquid
Dispatch by render locationsnippets/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

  1. Add the name to CartEvents in src/entrypoints/mini-cart/internals/core.ts.
  2. Add its payload type to CartEventDetailMap in the same file.
  3. Emit it with CartEventBus.emit instead of constructing a CustomEvent by hand, so every payload gets the external flag.
  4. Document it in Cart events.

Add a value that Liquid passes to JavaScript

  1. 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 on window.theme.
  2. When you add to window.theme, create the key only if it is missing, as in window.theme.x = window.theme.x || {}. Snippets run in no fixed order.
  3. Output the value with | json instead of wrapping it in quotes, so an apostrophe in a merchant's text cannot break the script.
  4. Add the property to src/@types/global.ts in the same commit. Mark it optional if only some pages render it.
  5. If the value is store-wide, check whether the other two layouts need the same change.

Add a theme setting

  1. Add it to the right group in config/settings_schema.json, or create a group.
  2. Use a valid setting type. config/settings_schema.json already contains one invalid type that Theme Check reports, so check any neighbouring setting before you copy it.
  3. Read it in Liquid as settings.<id>.
  4. Run npm run lint:fix and confirm the schema still validates.
  5. 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 status

In 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.

On this page