Theme demo catalog

A theme can ship its own products, categories and brands. They are seeded into your theme's demo store when it is provisioned, so your product sections have something to render.

This matters more than it sounds. Every product widget — categories, new-arrival, best-selling, filter-products, the product sliders — renders nothing on a store with no products. Before demo catalogs, a developer could build a demo store, pass the release gate, and never once see their own product sections working. The storefront merchants judged the theme by was half blank.

The folder is optional. Without it the demo store is seeded from the platform's generic catalog instead — which works, but a menswear theme demonstrating itself on unbranded goods is a weaker listing than one showing its own. If the folder does exist it must be valid: npm run validate checks it locally, and the server checks it again at submission.


Where it lives in the package

theme.zip
└── theme/
    ├── templates/            # default/system pages
    ├── header-footer/        # header & footer presets
    ├── landing-templates/    # theme landing pages
    └── demo-data/            # ← this page
        ├── categories.json
        ├── brands.json
        ├── products.json
        └── images/

In the kit it is src/themes/custom/demo-data/. npm run build copies the whole directory into dist/theme/demo-data/ and npm run package zips it — there is nothing to configure.


The files

categories.json

[
  { "ref": "cat-shirting", "name": "Shirting", "slug": "shirting", "image": "images/category-shirting.png" }
]

brands.json

[
  { "ref": "brand-house", "name": "House Label", "image": "images/brand-01.png" }
]

products.json

[
  {
    "ref": "p-001",
    "name": "Oxford Shirt — Ecru",
    "sku": "MRW-SHT-001",
    "price": 3800,
    "comparePrice": 4600,
    "stock": 24,
    "description": "Shown on the product page.",
    "categoryRefs": ["cat-shirting"],
    "brandRef": "brand-house",
    "images": ["images/product-shirt-01.png"]
  }
]

Only ref, name and price are required on a product.

field meaning
price what the customer pays
comparePrice the crossed-out "was" price. Optional, and only meaningful when higher than price
stock units seeded into the demo store's warehouse. Defaults to 25
categoryRefs one or more refs from categories.json
brandRef a ref from brands.json
images images/<file> for bundled files, or absolute https:// URLs

ref — why every row needs one

ref is your own stable key. Seeding maps ref → the row it created, which is how categoryRefs and brandRef are resolved.

Two rules, both enforced:

  • refs must be unique within a file
  • categoryRefs / brandRef must name a ref you actually declared

A typo in a categoryRef would otherwise seed a product into no category at all — invisible until a merchant notices the category page is empty.


Images

Bundle them in images/. Absolute https:// URLs are accepted, but stock photo links rot, and a demo store that loses its pictures six months from now is a support ticket — against a storefront merchants are still judging your theme by.

Only bundle images you have the right to redistribute. They ship inside the package the platform hosts and serves to merchants.

Placeholders in your own palette are a perfectly good answer. Both first-party themes generate flat two-tone PNGs from their design tokens rather than shipping photography.


Limits

products 40
per image 300 KB
whole demo-data/ folder 15 MB

The package is downloaded and unzipped on every demo-store provision, so this stays small on purpose. A demo store only has to show the theme working; it is not a real catalogue.


Making it count

Match your own templates:

  • If your home page leads with a categories row of six tiles, ship at least six categories.
  • If your product card draws a discount badge or a strikethrough, give some products a comparePrice so it is visible.
  • If you render a low-stock state, ship one product with a small stock.
  • Name things the way a real shop in your niche would. "Jamdani Handloom Saree" sells the theme; "Product 3" does not.

When it is seeded

On demo-store provision — that is, when your theme is approved, and again on any later provision of a store that has no products yet.

It is deliberately not re-seeded on a version upload. A demo store you have been editing is the storefront merchants receive at release, so re-seeding it from the package would throw away your work. Uploading a new version refreshes your widget registry, not your catalog.

Merchants never receive these products. A release copies pages, menus, widgets and chrome into the frozen release artifact — never the catalog. Their own products stay theirs.


Readiness

A demo store with no products raises a warning, not a blocker:

Your demo store has no products, so every product section renders empty — including on the preview merchants see.

You can still release. But a warning here means nobody — including you — has seen your product sections do their job.