Updates that keep your work
The engineering rules that make "survives its own updates" true. Every release, every
section ticket, and the update-simulation harness are bound by this document. Violating
any rule here is a release blocker, not a style issue.
What Shopify preserves on a theme update
Shopify's update process preserves the settings layer: config/settings_data.json and the
JSON templates (templates/*.json, section groups). Code files (layout/, sections/,
snippets/, assets/, locales/) are replaced by the new version.
The contract therefore has two halves: keep every merchant customization in the preserved
layer, and keep the one deliberate exception (the custom snippet namespace) out of the
replacement set.
Rule 1 - All merchant customization is settings data
No merchant-reachable customization may require editing theme code. Colors, fonts, spacing,
layout, and content are settings. One-off tweaks use the per-section hooks (Rule 3).
If a section ticket adds behavior a merchant can only reach by editing Liquid, the ticket
is incomplete.
Rule 2 - The settings schema is append-only
Within a major version, settings in config/settings_schema.json and section schemas may
be added or deprecated (label marked, ignored by code) but never renamed or
removed. Preserved settings_data.json from version N must map cleanly onto version
N+1's code with no meaning changes.
- Changing a default is allowed (existing stores keep their saved value).
- Changing an option's
valuelist entry is a rename - not allowed. Add a new option - Section renames are removals: a
templates/*.jsonentry pointing at a deleted section
instead and keep honoring the old value in Liquid.
type breaks the storefront. Section files may be added but never renamed or deleted
within a major version once released.
Rule 3 - Per-section customization hooks
Every section exposes two settings, rendered through snippets/section-custom.liquid:
{ "type": "header", "content": "Advanced customization",
"info": "One-off tweaks for this section live here as settings, so they survive theme updates. Most merchants never need these." },
{ "type": "liquid", "id": "custom_liquid", "label": "Custom Liquid",
"info": "Rendered at the end of this section. Survives theme updates because it is stored as a setting, not a code edit." },
{ "type": "textarea", "id": "custom_css", "label": "Custom CSS",
"info": "Plain CSS applied only to this section. Survives theme updates." }
and includes {% render 'section-custom', section: section %} after its markup. The
custom CSS is scoped to the section by nesting it under #shopify-section-<id> (CSS
nesting), so a merchant's tweak cannot leak into other sections.
sections/editorial-text.liquid is the reference implementation.
Rule 4 - The reserved custom snippet namespace
snippets/custom-*.liquid is merchant-owned:
custom-head.liquid- rendered at the end of<head>on every pagecustom-body-start.liquid- rendered right after<body>custom-body-end.liquid- rendered right before</body>
Contract terms:
1. Every Vellum release ships these files empty (a comment only).
2. The documented update process never copies over files matching
snippets/custom-*.liquid when overlaying a new version - merchant editions of these
files survive. The update-simulation harness asserts this on every release.
3. Theme code references the namespace only via the three stable include points in
layout/theme.liquid. Include points may be added in a major version, never removed.
4. No release may ship functional code inside the namespace (that would create merge
conflicts with merchant editions).
Rule 5 - The update overlay procedure
Updating a store from version N to N+1 (manual or automated) means:
1. Copy version N+1's code layer over the theme, excluding:
config/settings_data.jsontemplates/*.jsonand section group files (sections/*.json)snippets/custom-*.liquid
2. Leave everything preserved in place.
3. Run through the versioned upgrade guide for that release (usually: nothing to do).
This procedure is executable in CI as the update-simulation harness and is the definition
of an update for support purposes.
Enforcement
- CI: the update-simulation harness (deploy N -> customize -> overlay N+1 -> re-run
- Review: any PR touching
settings_schema.json, a section{% schema %}, or - Docs: the per-release upgrade guide states explicitly whether any deprecations
behavior suite) must be green for release. A renamed setting or shipped-over custom
snippet fails it.
layout/theme.liquid include points is reviewed against Rules 2-4.
occurred and what (if anything) a merchant must re-check.