Skip to Content
StoreOSv0.27.1
Themes

Theme CLI reference

Reference for the storeos theme commands — init, dev, check and package — their options, store data and connecting to the console.

storeos theme init [dir] [--blank]            Create a theme
storeos theme new widget <name> [--page p]    Add a widget and put it on a page
storeos theme new snippet <name>              Add a snippet
storeos theme dev [dir] [options]             Preview with live reload
storeos theme check [dir]                     Check the theme, the same way upload does
storeos theme package [dir] [--out file.zip]  Check and zip the theme for upload

[dir] is the theme folder. It defaults to the current folder, except for init, which creates ./my-theme. new works in the current folder. Run storeos theme --help for a summary.

The full command reference is at storeos theme. To install the CLI, see the CLI overview.


init

storeos theme init my-theme            # the full starter theme
storeos theme init my-theme --blank    # only the required files
storeos theme init .                   # in the current folder

The folder must not exist yet or must be empty. A .gitignore for zips is added too.

Option
--blankOnly layout/theme.fluid, config/document.json and assets/theme.css, with empty widgets/ and snippets/ folders. The home page starts with a heading and a paragraph

The full starter theme has a header, footer, hero, featured products, and a widget for every page (product, collection, page, blog, article, search), with snippets and translations. Read it to see how a complete theme fits together.


new

storeos theme new widget promo-banner                 # on the home page
storeos theme new widget size-guide --page product    # on the product page
storeos theme new widget button                       # restyle a built-in widget
storeos theme new snippet product-card

new widget writes widgets/<name>.fluid with a heading and a text setting to start from, and adds the widget to a page in config/document.json.

For a built-in widget name such as button or heading, it copies StoreOS's own markup instead, with the props the widget already gets. Change the markup and keep using those props.

Names are lowercase letters, numbers and dashes. An existing file is never overwritten.

Option
--page <page>The page to add the widget to: home (default), product, collection, page, blog, blog-post or search

dev

storeos theme dev
storeos theme dev --port 3000 --open
storeos theme dev --data store.json

Serves the theme from your folder with the same engine stores use, so what you see here is what a store renders. Nothing is zipped or uploaded.

Option
--port <n>Port to listen on. Default 9292; the next free port is used if it's taken
--host <host>Default localhost. Use 0.0.0.0 to open the preview from a phone on the same network
--storefront <url>Load the real shop, catalog and SEO from a running storefront API, e.g. http://127.0.0.1:4001
--data <file>Your own store data
--document <file>A theme document to use instead of config/document.json, e.g. one copied from a store's customizer
--openOpen the preview in your browser
--store <store>Print a direct link to the console customizer for this store. Also the tenant uid for --storefront when the address has no tenant subdomain
--console <url>Allow a console on a custom domain (see Console connection)

Files given with --data and --document are watched too.

Pages

URL
/, /products/:handle, /collections/:handle, /collections/all, /pages/:slug, /blog, /blog/:handle, /search?q=Your theme's pages, with the same routes as a store
/__theme/widgetsEvery widget in your theme on its own, with its default settings
/__theme/widgets/<type>One widget

Other pages, such as the cart and checkout, show a notice: StoreOS renders them, not the theme.

Saving files

You saveWhat happens
A .css file in assets/The stylesheet is swapped in the page without a reload, so scroll position and state are kept
Any other theme fileThe theme is re-read and checked, then the page reloads
A file with an errorThe page shows the error with the file and line, and the terminal prints it. Fixing it recovers
A widget that reads a props.<name> its schema doesn't listIt gets a guessed setting, and the terminal says so

Tailwind stylesheets are recompiled on every save.


Store data

There is no built-in sample catalog. Until dev has store data, the preview shows a waiting page. Give it data with Connect local theme in the console, with --storefront <url>, or with --data.

To use a JSON file, pass it with --data. It uses the same shapes as the Storefront API. Lists you leave out are empty:

{
  "shop": { "name": "My Shop", "currency": "BDT" },
  "collections": [{ "_id": "c1", "name": "Shoes", "slug": "shoes" }],
  "products": [
    {
      "_id": "p1",
      "title": "Runner",
      "handle": "runner",
      "price": 2500,
      "thumbnail": { "url": "https://example.com/runner.jpg" },
      "collections": [{ "_id": "c1", "name": "Shoes", "slug": "shoes" }]
    }
  ],
  "pages": [],
  "posts": []
}

An image is { "url": "…" }, or { "key": "Some label" } for a placeholder with that label.

To see your real store's data without writing JSON, connect the theme to the console or use --storefront.


Console connection

While dev runs, the console customizer can load your theme straight from your computer, with your store's real data:

  1. In the console: Online store → Themes → Uploaded themes → Connect local theme.
  2. http://localhost:9292 is filled in. Change it if dev printed another port, then click Connect.

You can open the console before or after starting dev: it connects when the server is up and reconnects if you restart it. The header shows the connection: updates when you save, connecting or dev server stopped.

  • Nothing is saved to the store. Save draft and Publish are replaced by Save to files (⌘S / Ctrl+S), which writes the document to config/document.json in the short form. If you started dev with --document, that file is written instead. Keys the customizer doesn't edit, such as prerender, are kept.
  • ⋯ → Save as widget defaults writes the selected widget's settings as the defaults in its {% schema %}, in the short form. This works for your own widgets, not built-in ones.
  • ⋯ → Copy JSON copies the document, the selected widget's props or its schema, if you'd rather paste them yourself.
  • Reset → Discard changes reloads everything from your config/document.json.
  • The terminal prints each file the console writes, e.g. ✎ config/document.json saved from the console.
  • New and changed widgets show up in the widget library as soon as you save them.
  • Only localhost addresses can be connected.

Which consoles can connect

The dev server only shares your theme with StoreOS consoles, and only they can save to it: https://console.storeos.dev, any other https://*.storeos.dev address, and consoles running on localhost. It checks the address each request comes from, so you don't need any options. Other websites can't read your theme or write to it. The console can only write config/document.json and the schemas of widget files that already exist.

If you use a console on your own domain, allow it with --console:

storeos theme dev --console https://admin.example.com

Browsers

Use Chrome, Edge or Firefox. Safari blocks an https page from loading http://localhost. Chrome may ask whether the console can access devices on your local network: allow it.


check

storeos theme check

Runs the same checks as upload and prints every problem it finds. Errors (✗) stop an upload:

  • layout/theme.fluid or config/document.json is missing
  • A folder or file type that isn't allowed
  • A .fluid file that doesn't parse
  • A {% schema %} with invalid JSON, a setting without a kind, or an unknown kind
  • config/document.json uses a widget the theme can't render
  • A Tailwind stylesheet doesn't compile

Warnings (!) are likely mistakes that still render:

  • A setting the markup never uses
  • Settings guessed from the markup
  • An unknown schema key or page name
  • A {% schema %} in a built-in widget, which is ignored
  • A built-in widget's markup that ignores the settings merchants change

Where it can, it suggests the fix:

  ! widgets/card.fluid: unknown {% schema %} key "lable" (did you mean "label"?)
✗ 1 error(s):
  - config/document.json: uses widget "crad" but the theme has no widgets/crad.fluid (did you mean "card"?)

It exits with code 1 when there are errors, so you can use it in CI. Warnings don't change the exit code. dev prints the same warnings when they change.


package

storeos theme package
storeos theme package --out dist/my-theme-1.2.zip

Checks the theme, compiles Tailwind stylesheets and writes a zip, by default <folder name>.zip in the current folder. Only the theme folders (layout, widgets, snippets, assets, config, locales) are included. Hidden files are left out.

Option
--out <file>Where to write the zip

Upload it in the console: Online store → Themes → Upload theme.


Troubleshooting

ProblemFix
doesn't look like a themeRun the command inside the theme folder, or pass the folder: storeos theme dev my-theme
already exists and isn't emptyinit only writes to a new or empty folder
This dev server can't save filesYour storeos theme is older than the console. Install the latest one and restart dev
The console says Dev server stoppedStart storeos theme dev again. The console reconnects by itself
The console can't connectCheck the port dev printed, use Chrome, Edge or Firefox, and allow local network access if asked
On macOS, the CLI is stopped as soon as it startsYou copied over the old file. Delete it first, then copy the new one

On this page