Introduction
Shopify’s theme settings empower store owners to tailor their storefronts without writing a single line of code. But tapping into the power of Liquid variables can take your customizations even further—enabling dynamic layouts, conditional features, and personalized experiences. In this guide, you’ll learn how to define and expose settings in settings_schema.json
, access them via Liquid in templates and sections, and combine variables with logic to build flexible, data-driven themes. By the end, you’ll understand how to leverage Shopify’s theming system like an expert, delivering tailored storefronts that scale with your brand.

Understanding Shopify Theme Settings and Liquid Variables
What Are Theme Settings?
Theme settings are user-facing options—colors, font sizes, toggles—that appear in the Shopify Theme Editor. They’re defined in the config/settings_schema.json
file and automatically render form controls for merchants to adjust.
What Are Liquid Variables?
Liquid variables store data—both static (from settings) and dynamic (from store objects like product
, cart
, or collection
). When you reference a setting’s ID, Shopify exposes its value as a Liquid variable (section.settings.color_brand
, for example).
Key Benefit: Combining settings with variables lets you write one template that adapts to myriad configurations without manual code changes per store.
Prerequisites and Setup
- Development Store or Live Duplication: Always work in a duplicated theme to prevent downtime.
- Shopify CLI & Theme Kit (Optional): For local development and live deployments.
- Code Editor: VS Code, Sublime, or your preference.
Clone or download your theme, then open the config/settings_schema.json
file to get started.
Step 1: Defining Custom Settings
Editing settings_schema.json
At the bottom of config/settings_schema.json
, add a new settings block:

jsonCopyEdit{
"name": "Custom Layout Settings",
"settings": [
{
"type": "select",
"id": "layout_style",
"label": "Layout Style",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "list", "label": "List" }
],
"default": "grid"
},
{
"type": "color",
"id": "highlight_color",
"label": "Highlight Color",
"default": "#ff0000"
},
{
"type": "checkbox",
"id": "show_badges",
"label": "Show “On Sale” Badges",
"default": true
}
]
}
type
: Control type (e.g.,select
,color
,checkbox
).id
: Unique identifier—becomes the Liquid variable name.label
: Display text in Theme Editor.options
(forselect
): Value/label pairs.default
: Fallback value.
Save and open the Theme Editor to see your new settings under “Custom Layout Settings.”
Step 2: Accessing Settings in Liquid
Referencing Section Settings
In a section file (sections/featured-products.liquid
), access settings via section.settings
:
liquidCopyEdit{% assign style = section.settings.layout_style %}
{% assign highlight = section.settings.highlight_color %}
{% assign badges = section.settings.show_badges %}
Conditional Rendering with Liquid
liquidCopyEdit<div class="products {{ style }}">
{% for product in collections.frontpage.products %}
<div class="product-card">
<h2>{{ product.title }}</h2>
{% if badges and product.compare_at_price > product.price %}
<span class="badge" style="background-color: {{ highlight }};">
On Sale
</span>
{% endif %}
<!-- rest of card -->
</div>
{% endfor %}
</div>
{% if badges %}
: Only show sale badges if the merchant enabled them.style
class: Toggles between.grid
and.list
layouts.- Inline
highlight
: Applies the chosen color.
Step 3: Structuring CSS for Dynamic Styles
Using Utility and Modifier Classes
Define base styles and modifiers in your stylesheet (assets/theme.css
):
cssCopyEdit.products.grid .product-card {
width: calc(33.333% - 1rem);
display: inline-block;
margin: 0.5rem;
}
.products.list .product-card {
width: 100%;
display: block;
margin: 0.5rem 0;
}
.badge {
color: #fff;
padding: 0.2rem 0.5rem;
border-radius: 4px;
font-size: 0.8rem;
}
Because the .products
container toggles classes based on layout_style
, your CSS responds automatically without extra JavaScript.
Step 4: Exposing Theme Settings in Templates
Not all customizations belong in sections—sometimes you need global settings. Add settings in settings_schema.json
under a "theme_settings"
block:

jsonCopyEdit{
"name": "Global Styles",
"settings": [
{
"type": "font_picker",
"id": "body_font",
"label": "Body Font",
"default": "Lato"
},
{
"type": "range",
"id": "base_spacing",
"label": "Base Spacing (px)",
"min": 4,
"max": 32,
"step": 4,
"default": 16
}
]
}
In your layout (layout/theme.liquid
), reference these via settings
:
liquidCopyEdit<style>
body {
font-family: {{ settings.body_font | json }};
margin: 0;
padding: {{ settings.base_spacing }}px;
}
h1, h2, h3 {
margin-bottom: {{ settings.base_spacing | times: 0.5 }}px;
}
</style>
settings.body_font
: Applies the selected font.settings.base_spacing
: Controls global padding and margins.
Step 5: Combining Settings and Dynamic Data
Featured Collection with Conditional Layout
In templates/index.liquid
, you can combine global and section settings:
liquidCopyEdit{% section 'hero' %}
{% section 'featured-products' %}
{% assign home_collection = settings.home_collection %}
{% if home_collection %}
<div class="home-collection">
<h2>{{ home_collection.title }}</h2>
{% for product in home_collection.products %}
{% render 'product-card', product: product, show_badges: settings.show_badges %}
{% endfor %}
</div>
{% endif %}
settings.home_collection
(if defined): Dynamically choose which collection to feature on the homepage.- Passing Parameters to Snippets: Use
render
with additional variables likeshow_badges
.
Expert Tips for Advanced Customization
- Use
json
Filter for Safety: Wrap font names or strings in| json
when outputting in CSS to ensure proper quoting. - Cache Section Settings with
assign
: Avoid repeated lookups—store settings in variables at the top. - Leverage
schema.presets
: Provide merchants with preconfigured setting combinations (e.g., light vs. dark mode). - Modularize Snippets: Offload repeated logic (badges, price formatting) into
snippets/product-badge.liquid
and include withrender
. - Validate Inputs: For
range
andtext
settings, use Liquid filters (| default: 0
,| strip
) to sanitize merchant inputs.

Conclusion
By defining intuitive settings in settings_schema.json
and harnessing Liquid variables in templates, sections, and stylesheets, you can transform a static theme into a dynamic, merchant-friendly powerhouse. Whether you’re toggling layouts, applying brand colors, or conditionally displaying elements, the combination of Shopify’s Theme Editor and Liquid gives you granular control without sacrificing ease of use. Start small—add a color picker or toggle—and progressively layer in more settings to deliver a highly customizable storefront that adapts to every merchant’s vision.