Appearance
Theme settings
Settings let hosts customise your theme — colors, labels, toggles — without touching code. You declare them in config/settings_schema.json; Stayblox renders the form, and your templates read the values from the settings global.
The format and example below are generated from the platform's reference theme, so they stay in sync with what the platform accepts.
Theme settings let hosts customise your theme without editing code. You declare them in config/settings_schema.json; Stayblox renders the form, and your templates read the values from the settings global.
Format
The file is an array of sections, each with a name and a list of fields. Each field has:
| Property | Meaning |
|---|---|
id | The setting key. Your templates read it as settings.<id>. |
type | Input type (see below). |
label | Label shown in the settings form. |
default | Default value before the host changes anything. |
fields | For a grid field only: nested fields grouped visually (their ids are still top-level settings). |
Field types in use
image_picker, color_picker, text, textarea, radio, select, code_editor
Example — config/settings_schema.json
json
[
{
"name": "theme_settings.logo.label",
"fields": [
{
"type": "image_picker",
"id": "logo_dark",
"label": "theme_settings.logo_dark.label"
},
{
"type": "image_picker",
"id": "logo_light",
"label": "theme_settings.logo_light.label"
},
{
"type": "image_picker",
"id": "favicon",
"label": "theme_settings.favicon.label",
"image_size": "128x128"
}
]
},
{
"name": "theme_settings.colors.label",
"fields": [
{
"type": "color_picker",
"id": "base_color",
"label": "theme_settings.base_color.label",
"default": "#2563eb"
}
]
},
{
"name": "theme_settings.social_media.label",
"fields": [
{
"type": "text",
"id": "social_link_facebook",
"label": "theme_settings.social_media_links.facebook.label",
"placeholder": "https://facebook.com/rentmave"
},
{
"type": "text",
"id": "social_link_instagram",
"label": "theme_settings.social_media_links.instagram.label",
"placeholder": "https://instagram.com/rentmave"
},
{
"type": "text",
"id": "social_link_x",
"label": "theme_settings.social_media_links.x.label",
"placeholder": "https://x.com/rentmave"
},
{
"type": "text",
"id": "social_link_linkedin",
"label": "theme_settings.social_media_links.linkedin.label",
"placeholder": "https://www.linkedin.com/company/rentmave"
},
{
"type": "text",
"id": "social_link_youtube",
"label": "theme_settings.social_media_links.youtube.label",
"placeholder": "https://www.youtube.com/rentmave"
},
{
"type": "text",
"id": "social_link_vimeo",
"label": "theme_settings.social_media_links.vimeo.label",
"placeholder": "https://vimeo.com/vimeo"
},
{
"type": "text",
"id": "social_link_tiktok",
"label": "theme_settings.social_media_links.tiktok.label",
"placeholder": "https://tiktok.com/@rentmave"
},
{
"type": "text",
"id": "social_link_snapchat",
"label": "theme_settings.social_media_links.snapchat.label",
"placeholder": "https://www.snapchat.com/add/rentmave"
},
{
"type": "text",
"id": "social_link_pinterest",
"label": "theme_settings.social_media_links.pinterest.label",
"placeholder": "https://pinterest.com/rentmave"
},
{
"type": "text",
"id": "social_link_tumblr",
"label": "theme_settings.social_media_links.tumblr.label",
"placeholder": "https://rentmave.tumblr.com"
},
{
"type": "text",
"id": "social_link_telegram",
"label": "theme_settings.social_media_links.telegram.label",
"placeholder": "https://t.me/rentmave"
}
]
},
{
"name": "theme_settings.pages.label",
"fields": [
{
"type": "image_picker",
"id": "pages_background_image",
"label": "theme_settings.pages_background_image.label",
"image_size": "1900x600"
}
]
},
{
"name": "theme_settings.footer.label",
"fields": [
{
"type": "textarea",
"id": "footer_about_text",
"label": "theme_settings.footer_about_text.label"
}
]
},
{
"name": "theme_settings.extra.label",
"fields": [
{
"type": "radio",
"id": "enable_cookie_notice",
"boolean": true,
"label": "theme_settings.enable_cookie_notice.label"
}
]
},
{
"name": "theme_settings.facility_icons.label",
"fields": [
{
"type": "select",
"id": "icon_weight",
"label": "theme_settings.icon_weight.label",
"helper_text": "theme_settings.icon_weight.helper_text",
"default": "regular",
"options": {
"thin": "theme_settings.icon_weight.options.thin",
"light": "theme_settings.icon_weight.options.light",
"regular": "theme_settings.icon_weight.options.regular",
"bold": "theme_settings.icon_weight.options.bold",
"fill": "theme_settings.icon_weight.options.fill",
"duotone": "theme_settings.icon_weight.options.duotone"
}
}
]
},
{
"name": "theme_settings.custom_css.label",
"fields": [
{
"type": "code_editor",
"id": "custom_css",
"label": "theme_settings.custom_css.label",
"helper_text": "theme_settings.custom_css.helper_text"
}
]
}
]Reading settings in a template
twig
<body style="--brand: {{ settings.primary_color ?? '#4f46e5' }}">
{% if settings.show_footer ?? true %}
<footer>…</footer>
{% endif %}Always provide a fallback (?? default) so a freshly installed theme renders before the host configures anything. On install, each field's default is seeded as the stored value.
Where values live
- You declare fields in
config/settings_schema.json. - Hosts edit values on the theme settings page; each field's
defaultis seeded on install, and values are stored per install. - Templates read them from the
settingsglobal, e.g.{{ settings.primary_color }}.
There is no theme_setting() function — settings are plain keys on the settings global. Always provide a fallback (?? default) so a freshly installed theme renders before the host configures anything.