Appearance
Theme structure
A theme is a directory of layout, views, sections, snippets, config, and assets, identified by a theme.json manifest. The details below are generated from the platform's validation rules and the reference theme, so they match exactly what the platform accepts.
The manifest: theme.json
Every theme carries a theme.json in the theme root identifying it (slug, name, semver version, optional description and changelog); see Stayblox CLI → manifest. The contract is the same whether you publish with the CLI or upload a .zip to your own site: the platform always reads the theme's identity from the manifest.
Files are stored by their path within the theme. Every package, whether a CLI publish or a private zip upload, carries the same theme.json manifest; the theme's slug, name, and version are always read from it. Beyond the manifest, what's required depends on the publishing path:
- Marketplace (CLI):
layout/theme.liquidmust exist. Config files (config/settings_schema.json,config/settings_data.json,config/menu.json,config/pages.json) must be valid JSON when present; missing ones are warnings. - Private zip upload: only a
layout/directory is required; there is no review step.
Reference layout
The cove theme shipped in the platform is a complete, minimal example:
cove/
assets/css/iziToast.min.css
assets/css/iziToast_custom.css
assets/css/theme.css
assets/js/app.js
assets/js/booking-status.js
assets/js/booking-widget.js
assets/js/card.js
assets/js/cart-page.js
assets/js/checkout-form.js
assets/js/contact-form.js
assets/js/iziToast.min.js
assets/js/newsletter-widget.js
assets/js/review-form.js
assets/js/storefront-api.js
config/blocks.json
config/menu.json
config/pages.json
config/settings_schema.json
lang/bg.admin.json
lang/bg.json
lang/en.admin.json
lang/en.json
layout/theme.liquid
locales/bg.json
locales/en.json
sections.json
sections/blog_posts.liquid
sections/email_signup.liquid
sections/faq.liquid
sections/featured_units.liquid
sections/gallery.liquid
sections/hero.liquid
sections/highlights.liquid
sections/location.liquid
sections/map.liquid
sections/rich_text.liquid
sections/stats.liquid
sections/testimonials.liquid
snippets/blog-post-card.liquid
snippets/footer.liquid
snippets/header.liquid
snippets/hero-banner.liquid
snippets/unit-card.liquid
theme.json
views/accommodation-detail.liquid
views/accommodations.liquid
views/blog-post.liquid
views/blog.liquid
views/booking-status.liquid
views/cart.liquid
views/checkout-confirmation.liquid
views/checkout.liquid
views/contact.liquid
views/index.liquid
views/maintenance.liquid
views/page.liquid
views/policy.liquid
views/review.liquidTop-level directories
| Directory | Purpose |
|---|---|
assets/ | CSS, JS, images, and fonts (assets/css/, assets/js/, …), served at a matching /assets/… URL: assets/css/app.css becomes /assets/css/app.css. Store preview images (desktop/mobile) are rendered on demand. |
config/ | settings_schema.json (host settings), menu.json (navigation), blocks.json (page-builder block types) / pages.json (seeds each page's initial blocks). |
lang/ | Optional admin-facing translation catalogs (<code>.admin.json) for your settings_schema.json / blocks.json field labels. Not shown to guests. |
layout/ | The theme shell, layout/theme.liquid. Required; the importer rejects a theme without it. |
locales/ | Storefront translation catalogs read by the t filter, one per locale code (e.g. en.json). |
sections/ | Configurable page-builder blocks, rendered into sections_html. See Templating → sections and blocks. |
snippets/ | Reusable partials pulled in with {% include %}. |
views/ | Page-level Liquid views, one per page type (index.liquid, page.liquid, accommodations.liquid, …). |
A
layout/directory is mandatory; importing a.zipwithout one fails.
How files are stored
Text files with these extensions are imported as editable theme files (editable later in the code editor):
liquid, css, js, json, svg, html, txt, xml, graphql
Files whose top-level directory is one of css/, js/, fonts/, images/, webfonts/ are stored under an assets/ prefix, so reference them at the matching /assets/… URL, e.g. /assets/css/app.css.
Binary files with these extensions are copied to the theme's public asset folder rather than stored as source:
woff, woff2, ttf, eot, png, jpg, jpeg, gif, ico, webp, mp4, webm
Required views
In addition to the importer constraints above, the following views are required for the theme to function correctly on all platform pages. Publish validation doesn't check for them (they aren't part of any config/*.json), but the routes that serve them fail at runtime without one:
| View | Location | Purpose |
|---|---|---|
booking-status.liquid | views/ | Public payment-status page (post-checkout redirect). |
review.liquid | views/ | Public post-stay review submission page (tokenized link from the review-request email). |
See Templating → booking-status.liquid and Templating → review.liquid for the variable contracts and the states to handle.
How files resolve at render time
Installing a theme doesn't copy its files. At render time a file is looked up by path among the site's own overrides first (a file the host edited in the code editor), falling back to the installed theme version for everything else. A host can customise just a few files without forking the whole theme, and files they never touch keep tracking the installed version.
Custom themes uploaded as a .zip have no marketplace version to fall back to, so all of their files live as site-level files from the start.
See Publishing for versioning and how updates flow to installed sites.