Skip to content

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 Liquid and config. A minimal theme:

my-theme/
  theme.json
  layout/
    theme.liquid
  views/
    index.liquid
  config/
    settings_schema.json
    menu.json
  locales/
    en.json
  assets/
    css/
      app.css

theme.json is 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."
}

layout/theme.liquid is the shell every page renders into, via content_for_layout. This is the one file that's actually required; importing a package without it fails:

liquid
<!doctype html>
<html lang="{{ locale }}">
  <head>
    <meta charset="utf-8">
    <title>{{ page_title }}</title>
    <link rel="stylesheet" href="/assets/css/app.css">
    {% if settings.base_color %}
      <style>:root { --brand: {{ settings.base_color }}; }</style>
    {% endif %}
  </head>
  <body>
    <nav>
      {% for item in menu %}
        <a href="{{ item.url }}">{{ item.translation_key | t: fallback: item.label }}</a>
      {% endfor %}
    </nav>
    <main>{{ content_for_layout }}</main>
  </body>
</html>

views/index.liquid is the home page:

liquid
<h1>{{ 'nav.home' | t }}</h1>
{% for unit_type in unit_types %}
  <article>
    <h2>{{ unit_type.name }}</h2>
    <a href="/accommodations/{{ unit_type.slug }}">{{ 'unit.details' | t }}</a>
  </article>
{% endfor %}

config/settings_schema.json declares the host-configurable settings (sections of fields; see Theme settings):

json
[
  {
    "name": "General",
    "fields": [
      { "id": "base_color", "type": "color_picker", "label": "Brand color", "default": "#4f46e5" },
      { "id": "show_footer", "type": "radio", "boolean": true, "label": "Show footer", "default": true }
    ]
  }
]

config/menu.json (navigation) rounds out the config; a config/blocks.json

  • config/pages.json pair seeds page-builder blocks on the home page and CMS pages, and config/settings_data.json is accepted too. All of them are optional; missing ones are validation warnings, not errors. See the reference layout.

locales/en.json supplies the strings your views read through the t filter:

json
{
  "nav": { "home": "Home" },
  "unit": { "details": "Details" }
}

assets/css/app.css:

css
body { font-family: system-ui, sans-serif; }

2. Preview on a development site

Zip the contents so layout/ 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 views 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 validate

The report tells you exactly what the marketplace requires (structure, valid config JSON, any graphql/*.graphql operations you shipped) 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

© Stayblox — Developer Platform