Skip to content

Config Files

The config directory contains JSON files that define your theme’s settings and metadata.

theme/
└── config/
└── settings_schema.json

The settings_schema.json file defines all configurable theme settings that appear in the CMS admin. When editors customize the theme, they interact with the fields defined here.

The schema is an array of setting groups:

[
{
"name": "group_name",
"label": "Group Label",
"settings": [
{
"type": "text",
"name": "field_name",
"label": "Field Label",
"default": "Default value"
}
]
}
]
PropertyTypeRequiredDescription
namestringYesUnique identifier for the group (used in templates)
labelstringYesDisplay label shown in admin UI
settingsarrayYesArray of setting field definitions

Settings are accessed via the settings global object:

{{ settings.group_name.field_name }}

For example, with this schema:

[
{
"name": "header",
"label": "Header",
"settings": [
{
"type": "color",
"name": "background",
"label": "Background Color",
"default": "#ffffff"
}
]
}
]

Access in templates:

<header style="background-color: {{ settings.header.background }}">
...
</header>

Here’s a comprehensive settings_schema.json demonstrating common patterns:

[
{
"name": "header",
"label": "Header",
"settings": [
{
"type": "upload",
"name": "logo",
"label": "Logo",
"relationTo": "media",
"filterOptions": {
"mimeType": { "contains": "image" }
}
},
{
"type": "color",
"name": "background",
"label": "Background Color",
"default": "#ffffff"
},
{
"type": "checkbox",
"name": "sticky",
"label": "Sticky Header",
"default": true
}
]
},
{
"name": "footer",
"label": "Footer",
"settings": [
{
"type": "richtext",
"name": "about",
"label": "About Text"
},
{
"type": "text",
"name": "copyright",
"label": "Copyright Text",
"default": "© 2024 Company Name"
}
]
},
{
"name": "colors",
"label": "Colors",
"settings": [
{
"type": "color",
"name": "primary",
"label": "Primary Color",
"default": "#0066cc"
},
{
"type": "color",
"name": "secondary",
"label": "Secondary Color",
"default": "#6c757d"
},
{
"type": "color",
"name": "accent",
"label": "Accent Color",
"default": "#ffc107"
}
]
},
{
"name": "typography",
"label": "Typography",
"settings": [
{
"type": "select",
"name": "heading_font",
"label": "Heading Font",
"options": [
{ "label": "System Default", "value": "system-ui" },
{ "label": "Georgia", "value": "Georgia, serif" },
{ "label": "Helvetica", "value": "Helvetica, Arial, sans-serif" }
],
"default": "system-ui"
},
{
"type": "select",
"name": "body_font",
"label": "Body Font",
"options": [
{ "label": "System Default", "value": "system-ui" },
{ "label": "Georgia", "value": "Georgia, serif" },
{ "label": "Helvetica", "value": "Helvetica, Arial, sans-serif" }
],
"default": "system-ui"
}
]
},
{
"name": "social",
"label": "Social Media",
"settings": [
{
"type": "array",
"name": "links",
"labels": {
"singular": "Social Link",
"plural": "Social Links"
},
"fields": [
{
"type": "select",
"name": "platform",
"label": "Platform",
"options": [
{ "label": "Facebook", "value": "facebook" },
{ "label": "Twitter/X", "value": "twitter" },
{ "label": "Instagram", "value": "instagram" },
{ "label": "LinkedIn", "value": "linkedin" },
{ "label": "YouTube", "value": "youtube" }
]
},
{
"type": "text",
"name": "url",
"label": "URL"
}
]
}
]
},
{
"name": "newsletter",
"label": "Newsletter",
"settings": [
{
"type": "checkbox",
"name": "enabled",
"label": "Enable Newsletter Signup",
"default": false
},
{
"type": "text",
"name": "heading",
"label": "Heading",
"default": "Subscribe to our newsletter"
},
{
"type": "textarea",
"name": "description",
"label": "Description"
},
{
"type": "text",
"name": "button_text",
"label": "Button Text",
"default": "Subscribe"
}
]
}
]
{# Simple values #}
<p>{{ settings.footer.copyright }}</p>
{# Colors in inline styles #}
<div style="background-color: {{ settings.colors.primary }}">
...
</div>
{# Conditional rendering #}
{% if settings.header.sticky %}
<header class="header--sticky">
{% else %}
<header>
{% endif %}

Use the _html suffix for richtext fields:

<div class="footer-about">
{{ settings.footer.about_html }}
</div>
{% if settings.header.logo %}
<img
src="{{ settings.header.logo | image_url: width: 200 }}"
alt="{{ settings.header.logo.alt | default: 'Logo' }}"
>
{% endif %}
<ul class="social-links">
{% for link in settings.social.links %}
<li>
<a href="{{ link.url }}" target="_blank" rel="noopener">
{{ link.platform }}
</a>
</li>
{% endfor %}
</ul>

A common pattern is to output theme settings as CSS variables in your layout:

{# In layouts/default.liquid #}
<style>
:root {
--color-primary: {{ settings.colors.primary }};
--color-secondary: {{ settings.colors.secondary }};
--color-accent: {{ settings.colors.accent }};
--font-heading: {{ settings.typography.heading_font }};
--font-body: {{ settings.typography.body_font }};
}
</style>

Then reference in your CSS files:

/* In assets/css/style.css */
body {
font-family: var(--font-body);
color: var(--color-primary);
}
h1, h2, h3 {
font-family: var(--font-heading);
}
.btn-primary {
background-color: var(--color-primary);
}

All standard input setting types are supported. See Input Settings for the complete reference.

TypeDescription
textSingle-line text input
textareaMulti-line text input
richtextRich text editor (access with _html suffix)
numberNumeric input
checkboxBoolean toggle
radioRadio button group
selectDropdown selection
colorColor picker
uploadMedia file selection
relationshipLink to CMS content
groupNested field group
arrayRepeatable field set
  1. Organize logically - Group related settings together (header, footer, colors, etc.)
  2. Provide defaults - Always set sensible default values
  3. Use clear labels - Help editors understand what each setting does
  4. Limit options - Don’t overwhelm editors with too many settings
  5. Use CSS variables - Output colors/fonts as CSS variables for flexibility
  6. Validate in templates - Always check if optional fields have values before using