Schema and settings
Control types, default values and stable identifiers.
A section is markup plus a schema
Every sections/*.html and blocks/*.html file has a separate file with the same name and the .schema.json extension. For example: sections/hero.html and sections/hero.schema.json. Do not place comments, trailing commas or expressions inside schema JSON.
<section>
<h1 data-text-field="[[ section.settings_path ]].title" gs-text="section.settings.title"></h1>
<template gs-slot="blocks"></template>
</section>*.schema.json:
{
"name": "Hero",
"settings": [
{
"type": "text",
"id": "title",
"label": "Heading",
"default": "Welcome"
}
],
"blocks": [
{
"type": "@theme"
}
],
"max_blocks": 12,
"presets": [
{
"name": "Hero"
}
]
}name labels the definition. settings defines its controls. blocks permits child types; it does not create instances. presets makes a definition available for adding from the editor. max_blocks limits dynamic children. Initial instances belong in page JSON.
Settings reference
| Type | Value and control | Required details / limitations |
|---|---|---|
text |
String, single-line input | id, label; use default |
textarea |
String, multiline input | Supports text dynamic sources |
url |
URL input | HTTP(S), root-relative, anchor, mailto:, tel: or empty |
image_picker |
Image URL string | Currently a URL input, not a media browser |
color |
Custom picker and HEX input | Six-digit HEX or transparent default |
range |
Slider and numeric input | min, max, positive step, numeric default; optional unit |
number |
Numeric input | Store a number, not a string |
select, radio |
Custom options menu | options with value / label; default must match an option |
checkbox |
Boolean control | Boolean default, not "true" |
font_picker |
Font selection | Inter, Arial or Georgia |
header, paragraph |
Sidebar information | content; no persisted setting |
[
{"type":"header","content":"Appearance"},
{"type":"range","id":"radius","label":"Corner radius","min":0,"max":48,"step":1,"default":16,"unit":"px"},
{"type":"color","id":"background","label":"Background","default":"#ffffff"},
{"type":"checkbox","id":"show_link","label":"Show link","default":true},
{"type":"select","id":"alignment","label":"Alignment","default":"left","options":[{"value":"left","label":"Left"},{"value":"center","label":"Center"}]}
]Apply numeric units in markup, for example border-radius:{{ block.settings.radius }}px. Store 16, not "16px". A unit in the control label does not add CSS automatically.
Defaults and saved values
Set a meaningful default for every editable field. The editor and renderer use defaults only when a saved value is missing. An empty string, zero and false remain intentional values. Opening an editor should not save a document.
Preset settings are initial values when adding an instance; they are not a migration for existing instances. Changing a default may affect previously unset settings. Explicitly saved values remain. Keep IDs and types stable across releases.
IDs start with a letter or underscore and use letters, digits, underscores and hyphens, up to 80 characters. Do not use constructor, prototype or __proto__. Limit a settings array to 100 entries. Unknown setting IDs are rejected on save.
Practical editing contract
A schema control does not automatically make every HTML node clickable. Add editor bindings for inline text and card editing. Do not add native color or select controls inside the theme to imitate the editor: the platform supplies consistent controls from schema.