settings_data.json: Storage & Presets
TL;DR: How merchant setting values are actually stored, the current/presets/platform_customizations structure, hard limits, and what switching a preset really changes.
config/settings_data.json stores the values for whatever settings_schema.json declares. It’s the file the theme editor actually writes to every time a merchant changes something. Facts on this page are verified directly against shopify.dev’s settings_data.json reference.
Required structure
Section titled “Required structure”| Object | Required | Description |
|---|---|---|
current | Yes | Every setting value currently active in the theme editor |
presets | Yes | One object per theme preset, in the same shape as current |
platform_customizations | No | Added automatically by Shopify if a merchant uses a platform-controlled setting — you never write this yourself |
{ "current": { "color_page_bg": "#FFFFFF" }, "presets": { "Default": { "color_page_bg": "#000000" } }}Any time a merchant changes a setting in the theme editor, current updates immediately to reflect it.
Hard limits, not just guidelines
Section titled “Hard limits, not just guidelines”These aren’t stylistic recommendations — they’re enforced platform limits:
- A theme can’t contain more than five presets total.
settings_data.jsoncan’t exceed 1.5MB.
Plan your preset strategy (see Theme Presets) with the five-preset ceiling in mind from the start, rather than discovering it after building a sixth.
What switching a preset actually changes: presentational settings only
Section titled “What switching a preset actually changes: presentational settings only”This is the single most commonly misunderstood part of the whole preset system. Selecting a different theme preset doesn’t overwrite every setting value — only “presentational” ones.
Presentational settings are the input types tied to a visual style, not to content:
checkbox, color, color_background, color_palette, color_scheme,color_scheme_group, font_picker, number, radio, range, select// ✅ Switches when a merchant picks a different preset — these are// presentational: colors, fonts, numeric/toggle style choices{ "type": "color", "id": "color_primary" }{ "type": "font_picker", "id": "type_heading_font" }{ "type": "range", "id": "border_radius" }// ❌ Does NOT switch when a merchant picks a different preset —// these hold content, not style, and a preset switch leaves them alone{ "type": "text", "id": "announcement_message" }{ "type": "image_picker", "id": "hero_image" }{ "type": "url", "id": "cta_link" }If you’re building a theme preset expecting it to also swap out a merchant’s hero image or announcement text, it won’t — only the presentational-type settings listed above are affected. A preset genuinely changing content, not just style, requires editing that preset’s "sections" data directly (see Theme Presets), not relying on the automatic preset-switch behavior.
platform_customizations: don’t touch it
Section titled “platform_customizations: don’t touch it”Shopify exposes a custom CSS setting directly in the theme editor, at both the theme and section level. You can’t add, hide, or remove this setting from your schema — it’s built into the platform. Any custom CSS a merchant adds through it is stored in the platform_customizations object’s custom_css attribute (or, for section-level custom CSS, in that section’s own JSON template data).
As a theme developer, never add this setting yourself, and never edit its value once a merchant has set one. If you want to offer CSS customization, do it through your own theme settings feeding into a {% stylesheet %} tag (see CSS in Shopify), not by touching this platform-owned mechanism.
settings_data.json holds real merchant data once installed
Section titled “settings_data.json holds real merchant data once installed”How they connect: the setting id links them together
Section titled “How they connect: the setting id links them together”A setting’s id in settings_schema.json is the same key settings_data.json, and every {{ settings.x }} reference in Liquid, uses to read or write its value. Treat a shipped id as permanent, the same way you’d treat a product SKU once it’s in customers’ order history:
// settings_schema.json defines the setting exists, with this id:{ "type": "color", "id": "color_primary", "label": "...", "default": "#1a5f4f" }// settings_data.json stores a value under that exact id:{ "color_primary": "#1a5f4f" }{# Liquid reads it by the same id: #}{{ settings.color_primary }}// ❌ WRONG — renaming the id breaks the link. Every merchant who// already customized "color_primary" now has an orphaned value in// their settings_data.json, and the newly-named setting falls back// to its schema default, silently discarding their customization{ "type": "color", "id": "brand_color_primary", "label": "...", "default": "#1a5f4f" }If a setting truly needs renaming, treat it as a major-version change (see After Approval) with a real migration path, not a silent rename.
A changed schema default doesn’t reach existing merchants
Section titled “A changed schema default doesn’t reach existing merchants”// You change this default from #1a5f4f to #2b2b52 in settings_schema.json...{ "type": "color", "id": "color_primary", "default": "#2b2b52" }A merchant who installed the theme last month, and never touched the color setting, is still on #1a5f4f. That value was already written into their store’s settings_data.json the moment they installed the theme. Changing a schema default only affects merchants who install the theme after the change. If every existing merchant needs to see a new default, a schema change alone won’t do it — that requires a separate migration step.
Do / Don’t
Section titled “Do / Don’t”| ✅ Do | ❌ Don’t |
|---|---|
| Plan presets with the hard 5-preset ceiling and 1.5MB file-size limit in mind, not as an afterthought. | Building more than five theme presets and discovering the platform limit only when a submission fails. |
| Remember that switching a preset only changes presentational-type settings. Design your presets around that limitation, not around an assumption that everything switches. | Assuming a theme preset swaps out content settings (text, images, links) the same way it swaps colors and fonts — it doesn’t. |
Never add or edit the platform-controlled custom_css/platform_customizations setting yourself. | Manually adding or editing a custom_css setting, which conflicts with the platform-controlled mechanism Shopify already provides. |
Treat a setting id as permanent once shipped, and a schema default change as something that only reaches fresh installs. | Renaming a setting id without a migration plan, silently discarding merchant customizations. |
| — | Assuming a changed schema default reaches already-installed merchants. It only affects fresh installs. |
Key takeaways
Section titled “Key takeaways”- Required:
current,presets. Optional, Shopify-managed:platform_customizations. - Hard limits: 5 presets max, 1.5MB file size max.
- A preset switch changes only presentational settings (
color,color_background,color_palette,color_scheme,color_scheme_group,font_picker,checkbox,number,radio,range,select) — never content settings. - Never touch the platform-controlled
custom_css/platform_customizationssetting yourself. - A setting
idlinks schema, data, and Liquid together — treat it as permanent once shipped.
Further reading
Section titled “Further reading”- settings_schema.json: Rules & Conventions: the definition file these values are shaped by
- Theme Presets: extending
presetsto support more than one theme style - Settings Conventions & Best Practices: the pre-ship checklist for both files together
settings_data.json(shopify.dev)