{% schema %} and {% endschema %} in a section or standalone block.
Define a section schema
A section schema can use these top-level fields:Limit a section to certain templates
Useenabled_on to allow a section only on the templates you list.
In the Page Editor, the section then appears under Not available here on every other template.
This section is allowed only on product templates:
enabled_on is available on every template.
Lint accepts disabled_on, but the editor ignores it, so list the allowed templates in enabled_on instead.
Define a setting
Every setting needs a supportedtype.
Every value-producing setting needs a unique, non-empty id within its settings array.
Use the ID to read the saved value:
Section and block controls ignore
unit and placeholder.
The theme panel reads unit on typography presets. See settings schema.
Keep IDs stable after a theme ships.
Changing an ID disconnects the schema from existing saved values.
Choose a setting type
Section and block settings render the same control for each type, with one exception: blocks do not acceptimage.
Use image_picker, which renders the same control in both.
In a block, a type without a control renders the word Unknown instead of an input.
Where an alias is shown, use one spelling consistently within a theme.
Settings in config/settings_schema.json render in the theme panel, which supports fewer types. See settings schema.
Text and URL
{{ company.name }}.
Fluid renders Liquid tags in saved setting values before your template reads them, so the page shows the current value.
The url picker lists store destinations, such as the home page, pages, products, collections, categories, posts, and media.
It saves the selected destination’s URL.
Editors can also type any URL.
Numbers
Define
min, max, and step on every range.
Without them, the slider runs from 0 to 100 in steps of 1.
number for open-ended values.
min, max, and step are optional; when set, the editor keeps entries between min and max.
number field, so give the value a fallback in Liquid:
Choices
Use
label and value for each explicit select or radio choice:
{% if section.settings.columns == '3' %}.
To share one list of choices across several settings, use an option group.
Color and fonts
Apply a
color_background value with the background property.
background-color ignores gradients.
options, or point options at an option group.
Without options, the picker offers system fonts: System UI, Apple System, Segoe UI, Roboto, Helvetica, Arial, and Sans Serif.
Images, video, and media
Each picker also shows an alt text field.
The editor saves alt text in a companion setting named
<id>_alt, so do not declare it yourself.
Choosing a new image or video clears the alt text.
Render a picker’s value with the media_tag filter, which builds responsive markup and renders nothing for an empty value:
Read a media picker
Amedia_picker saves an object, because it carries both the file and its embed options:
url from the object: {{ section.settings.banner_media.url }}, not {{ section.settings.banner_media }}.
embed_settings can be missing, so check the object before you read nested values.
A positive fluid_media_id identifies a Fluid media item, which you render with the media widget.
The ID can be 0 for a plain file, so compare it with > 0.
Liquid treats 0 as true, so != blank does not work here.
embed_type maps to the widget’s embed-type attribute:
See the media widget for its other attributes.
Layout
Corner and side values are numbers of pixels.
A value linked to a theme preset is a CSS variable reference, such as
var(--spacing-lg).
Padding and radius presets come from the padding and corner_radius groups, and border and overlay colors from color_schema.
See linked CSS presets.
Add px only to plain numbers:
{ "width": "2px", "color": "#d0d5dd" }.
A gradient overlay saves an object like this:
mode is solid or gradient, and gradientType is linear or radial.
opacity and position run from 0 to 100; position is optional.
A color can be a hex value or a var(--...) preset reference.
Render nothing when enabled is false.
Organization
Useheader to group the settings that follow it:
content, or its label.
The first group opens by default, and settings before the first header appear above all groups.
A group disappears when its header’s visible_if is false, or when every setting in it is hidden.
A header organizes controls.
It does not create a value that you read in Liquid.
Resource selectors
Resource pickers save record IDs. Fluid resolves the following setting types into Liquid resource values before your template reads them:media has no control in the section or block panel.
Set its value to a media ID or slug in a preset.
An unset resolved setting is an empty object, or an empty array for product_list.
Liquid treats an empty object as true, so test it with != blank:
Let editors choose several products
Useproduct_list when the editor should choose several products.
Set limit to cap the selection.
Iterate the resolved value:
Pickers that Fluid does not resolve
These types also open a picker, but Liquid receives the saved ID, or an array of IDs:
Look the records up yourself, or use a resolved type instead.
Types from other platforms
fluid theme lint rejects these types with Invalid settings type.
Use the Fluid equivalent:
Show settings conditionally
Addvisible_if to show a setting only when a condition is true.
Write the condition as an expression, with or without {{ }}:
section.settings.<id>.
A block setting’s condition can read block.settings.<id> as well as section.settings.<id>.
&& and || work as and and or.
A value can be a setting path, a quoted string, a number, true, false, or null.
and binds tighter than or.
A string compared with a number compares as a number, so '3' == 3 is true.
visible_if only hides the control in the editor.
A hidden setting keeps its saved value, and Liquid still receives it, so check the same condition in your template.
If the editor cannot evaluate a condition, it shows the setting.
The theme panel ignores visible_if.Define inline blocks
Inline blocks belong to one section. A block definition needstype and name when it defines settings.
section.blocks:
type.
Use @theme to accept public standalone blocks and @app to accept compatible extension blocks.
See blocks and components for rendering and nesting patterns.
Add presets
A preset can provide a displayname, picker category, initial settings, and initial blocks.
Reuse option groups
Use an option group when several section or block settings should share a choice list defined by the root theme. This keeps choices such as type scales consistent across the editor. First, addoption_group metadata to settings in config/settings_schema.json:
option_group.id contributes one choice.
The editor uses option_group.label as the choice label and option_group.value as its saved value.
Duplicate values are collapsed to the first matching choice.
Then set options to the plain option-group ID:
_, and - in an option-group ID.
If the group is missing or malformed, the editor cannot resolve choices for the setting.
An explicit options array continues to work and takes precedence over option-group resolution.
See root theme configuration for the rest of the settings flow.
Validate before publishing
Before you publish a schema:- Confirm that the schema body is valid JSON.
- Give each value-producing setting a unique, non-empty ID.
- Use only supported setting types, and
image_pickerrather thanimagein blocks. - Use
plaintext, nottext, for values that go into attributes, CSS, or URLs. - Test resolved resource settings with
!= blank. - Define block
settingsas an array. - Give inline blocks a
name. - Confirm that preset values match declared IDs and block types.
- Confirm that named standalone blocks exist.
- Test default and edited values in the visual editor.
fluid theme lint --json to catch schema and reference problems before you push.
See the CLI guide for the complete local workflow.