Skip to content

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.liquid must 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.liquid

Top-level directories

DirectoryPurpose
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 .zip without 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:

ViewLocationPurpose
booking-status.liquidviews/Public payment-status page (post-checkout redirect).
review.liquidviews/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.

© Stayblox — Developer Platform