Appearance
Getting started
Scaffold a minimal theme, preview it on a development site, and validate it with the CLI.
1. Create the files
A theme is a folder of Twig and config. A minimal theme:
my-theme/
theme.json
pages.twig
layouts/
app.twig
templates/
home.twig
partials/
seo.twig
config/
settings_schema.json
menu.json
templates.json
css/
app.csstheme.json — the manifest that identifies your theme on the platform. The same contract is used everywhere: CLI publishing and private zip uploads both read the theme's slug, name, and version from it:
json
{
"slug": "my-theme",
"name": "My Theme",
"version": "1.0.0",
"description": "A minimal starter theme."
}layouts/app.twig — the shell every template extends:
twig
<!doctype html>
<html lang="{{ app.locale }}">
<head>
<meta charset="utf-8">
<title>{{ general_settings.site_name ?? 'Stayblox' }}</title>
{% include 'partials/seo.twig' %}
<link rel="stylesheet" href="{{ theme_asset('css/app.css') }}">
</head>
<body style="--brand: {{ settings.primary_color ?? '#4f46e5' }}">
<nav>
{% for item in menu_items %}
<a href="{{ item.resolved_url }}">{{ item.label }}</a>
{% endfor %}
</nav>
{% block content %}{% endblock %}
</body>
</html>templates/home.twig:
twig
{% extends 'layouts/app.twig' %}
{% block content %}
<h1>{{ 'nav.home' | trans }}</h1>
{% for unitType in featured_unit_types %}
<article>
<h2>{{ unitType.name }}</h2>
<a href="{{ route('home') }}">{{ t('view_details') }}</a>
</article>
{% endfor %}
{% endblock %}pages.twig — the dispatcher that renders CMS pages (blog posts, custom pages) by including the matching template. Marketplace validation requires it:
twig
{% extends 'layouts/app.twig' %}
{% block content %}
{% include 'templates/' ~ template.slug ~ '.twig' %}
{% endblock %}config/settings_schema.json — the host-configurable settings (sections of fields; see Theme settings):
json
[
{
"name": "General",
"fields": [
{ "id": "primary_color", "type": "color", "label": "Primary Color", "default": "#4f46e5" },
{ "id": "show_footer", "type": "toggle", "label": "Show Footer", "default": true }
]
}
]config/menu.json (navigation) and config/templates.json (page templates) round out the config — see the reference layout.
css/app.css:
css
body { font-family: system-ui, sans-serif; }
a { color: var(--brand); }2. Preview on a development site
Zip the contents so layouts/ sits at the archive root:
bash
cd my-theme
zip -r ../my-theme.zip .In a development site, go to Themes → Manage themes → Upload theme and upload the .zip — the theme's slug, name, and version come from theme.json. Activate it, then open the storefront. Use the in-browser code editor to tweak templates and assets, and the theme settings page to see your settings_schema.json rendered as a form.
3. Validate with the CLI
When you're aiming for the marketplace, install the Stayblox CLI and validate from the theme directory:
bash
npm install -g @stayblox/cli
stayblox login
stayblox theme validateThe report tells you exactly what the marketplace requires (structure, valid config JSON, Twig lint with line numbers) before you ever publish. When it passes, stayblox theme push publishes a private draft and stayblox theme push --submit sends it for review — see Publishing.
Next
- What's available in templates → Templating
- Make it configurable → Theme settings
- Package layout & rules → Theme structure
- Publish it → Publishing · Stayblox CLI