Ship demo content with your theme so developers and merchants can explore its layouts with useful examples. Local previews and Theme Store previews read this content. Installing the theme does not create these products, pages, or menus in a merchant’s store.
Files and first preview#
Place the base pack at demo/catalog.json and its images under demo/images/. Reference images by filename, such as mug.webp. Use lowercase, hyphen-separated handles and keep them unique within each resource type. The pack uses schema_version 1. Prices are exact decimal strings in shop.currency_code; changing the currency does not convert prices. shop.locale controls preview formatting, and shop.country_code sets the sample shop country.
{
"schema_version": 1,
"shop": {
"name": "Everyday Goods",
"currency_code": "USD",
"locale": "en",
"country_code": "US"
},
"products": [
{
"handle": "ceramic-mug",
"title": "Ceramic Mug",
"images": [
"mug.webp"
],
"price": "18.50"
}
],
"collections": [
{
"handle": "everyday",
"title": "Everyday Essentials",
"products": [
"ceramic-mug"
]
}
],
"menus": [
{
"handle": "main",
"items": [
{
"title": "Home",
"target": "home"
},
{
"title": "Shop",
"target": "shop",
"children": [
{
"title": "Everyday Essentials",
"target": "collection:everyday"
},
{
"title": "Explore",
"target": "label",
"children": [
{
"title": "Ceramic Mug",
"target": "product:ceramic-mug",
"open_in_new_tab": true
}
]
}
]
}
]
}
]
}
Add demo/images/mug.webp before checking this example. Every referenced product, collection, page, article, and image must exist in the resolved pack. A broken reference stops validation and names the affected file and item.
tringify theme build
tringify theme check
tringify theme preview
tringify theme context --page product --entity ceramic-mug
Nested menus#
Each menu has a handle, such as main or footer, and an items array. Each item requires title and target. Add children for nested navigation, and optionally set open_in_new_tab to true. A label target needs at least one child and has no link. A parent may also have a destination: keep that destination accessible separately from the control that expands its children. Starter uses a View All link inside the expanded group.
Target |
Destination |
|---|---|
home, shop, collections, categories, vendors, brands |
The corresponding overview page |
blog, cart, search |
The blog index, cart, or search page |
product:your-handle, collection:your-handle |
A product or collection in the demo pack |
category:your-handle, vendor:your-handle, brand:your-handle |
A category, vendor, or brand in the demo pack |
page:your-handle, blog:your-handle |
A custom page or article in the demo pack |
label |
A group of child items without its own destination |
Use these targets in demo data instead of arbitrary URLs. The preview resolves them within the selected theme and style. In sections, use the resolved menu item’s title, url, children, and open_in_new_tab fields. Give menu toggles accessible names, retain visible keyboard focus, and preserve access to parent destinations on touch screens. Replace your-handle with the matching resource handle from the demo pack.
Product details, metafields and stock#
A product can carry a short_description, and products, variants, collections, categories, vendors and brands can carry metafields, so sections that read them show real content in previews. Write metafields as an object of namespaces, each holding keys and values. A value is text, a number, true or false, or a list of text: the same values a store's text, integer, decimal, boolean and list metafields give a theme. Previews expose them as product.metafields.namespace.key, variant.metafields, collection.metafields and on category, vendor and brand pages. A product whose vendor matches a demo vendor's name gets that vendor as product.vendor_ref, with its metafields, as on a store. Namespaces and keys use lowercase letters, digits and underscores and start with a letter or digit. Each record can have up to 24 metafields across all namespaces, each text up to 4,000 characters and each list up to 50 entries; a short_description can be up to 500 characters.
{
"handle": "empty-pool",
"title": "Empty Pool",
"vendor": "Ana Ruiz",
"short_description": "A municipal pool in Seville, drained for the winter.",
"metafields": {
"art": {"year": "2023", "edition_size": 25, "original": false}
},
"options": [{"name": "Size", "values": ["40 × 50 cm", "60 × 75 cm"]}],
"variants": [
{"title": "40 × 50 cm", "options": ["40 × 50 cm"], "stock": 2,
"metafields": {"art": {"width_cm": 40, "height_cm": 50}}},
{"title": "60 × 75 cm", "options": ["60 × 75 cm"], "stock": 0,
"metafields": {"art": {"width_cm": 60, "height_cm": 75}}}
],
"images": ["empty-pool.webp"],
"price": "14500.00"
}
stock works as it does in a store. A product without variants and with stock 0 is sold out. A variant is sold out when it has available set to false or stock 0, and a product is available while any of its variants is. Leave stock out for untracked stock. Include a sold-out product and the empty states too: a store's products often have none of these values.
Pack limits#
Content |
Maximum |
|---|---|
Base JSON file or each style overlay |
768 KiB |
Products |
48 |
Variants per product |
12 |
Images per product |
8 |
Collections |
16 |
Categories, vendors, and brands |
16 of each |
Blog posts and custom pages |
12 of each |
Sample cart lines |
8 |
Menu depth |
3 levels, counting the top level |
Sibling menu items |
16 in each items or children array |
Total menu items |
96 per menu, including all descendants |
These limits apply to the packaged demo content. They do not describe a merchant’s product catalog limits. Use a focused selection of products to demonstrate image proportions, long names, variants, sale prices, empty states, and mobile layouts.
Style-specific content#
Add demo/styles/Editorial.json for a style preset named Editorial; use your preset’s exact name for other styles. An overlay can provide shop fields or content lists. Supplied shop fields override the base values; each supplied list replaces that entire base list. Lists are not merged by handle. Keep referenced products and images available after the replacement, and check every style before packaging.
The limits apply to the base pack and to each style's pack after its overlay is applied. A style can also ship its own page layouts in templates/styles/; see Theme package structure. Previews of a style use its templates and its overlay together.
Validation messages#
The theme tool reports a readable error with file and reason details when available. Edit the source under src/sections/ when that is how your theme is authored, rebuild, then check again. Do not fix a generated sections/*.vasc file while leaving its source unchanged.
Theme validation failed
File: demo/catalog.json
Reason: menu "main", item "Ceramic Mug": target "product:missing" references an unknown product
For automation, the themecheck validator from the theme tools releases, which the Tringify CLI downloads for you, accepts -json and returns valid, error, code, and details on validation failures. Read code for the error category and details for the affected resource; wording may change. Stop packaging or publishing when the process exits with an error.
Finish in a development store#
Demo previews let you inspect rendering, navigation, styles, and responsive layouts. Verify cart changes, Buy Now, customer access, search results, and app-provided content against a development store before release. Use the public CTX reference for section data; sample content is not proof that a live integration works.