Theme package structure

The required files, optional capabilities, manifest rules, and archive limits for a Tringify theme.

A Tringify theme is uploaded as a ZIP archive. The archive is the installable package, not necessarily your source repository: build scripts, source maps, tests, and source folders may stay in your repository, but they must not be included in the uploaded ZIP unless they match an allowed package path below. Put theme.json and tokens.json at the root of the archive; do not wrap the package in an extra directory.

Required foundation#

Path

Requirement

theme.json

Required. Declares schema version 3, the theme identity, its section index, and its surface policies.

tokens.json

Required. Must be a JSON object. It contains the design tokens used by the theme.

sections/.vasc

At least one theme section is required. Every section file must be listed exactly in theme.json and its embedded schema name, kind, and target must agree with the manifest entry.

templates/.json

Seeds the ordered section composition for a surface. A template is required for every surface whose policy has a required section. Marketplace themes must also cover the complete platform surface floor.

theme.json surfaces

At least one editable platform surface must be declared. Each policy lists the section types that are required or may be added on that surface.

Complete package allowlist#

text
theme.json                                required manifest
tokens.json                               required design-token object
sections/<name>.vasc                      theme sections
blocks/<name>.vasc                        reusable theme blocks
templates/<surface>.json                  base and alternate compositions
templates/styles/<preset>/<surface>.json  a style's own compositions
config/settings_schema.json               global theme settings
config/presets/<preset>.json              theme styles: named whole-theme setting values
config/metafields.json                    metafield definitions the theme needs
locales/<locale>.json                     shopper-facing theme strings
locales/<locale>.schema.json              editor labels
assets/<file>                             fonts, raster images and short video loops
demo/catalog.json                         optional demo catalog
demo/styles/<preset name>.json            demo overlay for a theme style
demo/images/<file>                        raster images used by the demo catalog

Asset and archive limits#

Limit

Rule

Files

At most 600 files in one archive, style templates included.

Uncompressed size

At most 192 MiB across the complete archive.

Individual file

At most 1 MiB per file. Video assets (.mp4 and .webm) may be up to 8 MiB each.

assets/

One directory level. Allowed extensions: .woff2, .woff, .png, .jpg, .jpeg, .webp, .gif, .mp4, and .webm.

demo/images/

One directory level. Allowed extensions: .png, .jpg, .jpeg, .webp, and .gif.

Locale files

Directly under locales/. Each file is a flat JSON object whose keys and values are strings.

theme.json#

The manifest is self-contained: there is no separate surfaces file. source must be uploaded; status must be draft or published. name is required and may contain up to 80 characters. default_locale becomes required when the package contains locale files. exported_from and section origin are provenance written by theme exports; they do not replace any section or surface declaration.

json
{
  "schema_version": 3,
  "name": "Acme",
  "source": "uploaded",
  "status": "published",
  "default_locale": "en",
  "sections": [
    {
      "name": "acme-hero",
      "kind": "section",
      "file": "sections/acme-hero.vasc",
      "origin": "override"
    }
  ],
  "surfaces": [
    {
      "surface_key": "home",
      "required_sections": ["acme-hero"],
      "allowed_sections": []
    }
  ]
}

A surface may list theme-owned sections and platform built-in sections. A section cannot appear in both required_sections and allowed_sections, and each list must be free of duplicates. Only registered, theme-editable surfaces are accepted.

Templates#

A template filename must match its page_type exactly. Positions are zero or greater and unique within the template. A section type may appear at most once on a surface, every required section appears exactly once, and every section must be permitted by that surface policy. If a section declares blocks, its template instance must include an explicit settings.blocks array, which may be empty.

json
{
  "page_type": "home",
  "sections": [
    {
      "type": "acme-hero",
      "position": 0,
      "settings": {}
    }
  ]
}

Style templates#

A theme style is a preset in config/presets/. Besides its setting values, a style can ship its own page layouts: put its template for a page in templates/styles//<page_type>.json, where is the preset's file name without .json. For config/presets/editorial.json, the Editorial style's home page is templates/styles/editorial/home.json. A style ships any subset of the theme's templates; every page it does not ship uses templates/<page_type>.json.

text
config/presets/editorial.json          {"name": "Editorial", "settings": {...}}
config/presets/market.json             {"name": "Market", "settings": {...}}
templates/home.json                    every style except Editorial
templates/product.json                 every style
templates/styles/editorial/home.json   the Editorial home page
demo/styles/Editorial.json             demo content for Editorial

Rule

Detail

Checks

A style template is checked exactly like templates/<page_type>.json, including the marketplace checks: its sections must be in the theme and allowed on the page, setting values must be valid, required sections appear once, and positions are unique.

Folder name

The folder must be the file name of a preset in config/presets/. Demo overlays are different: demo/styles/ files use the preset's name.

Pages

A style replaces pages the theme has a template for. It cannot add a page that has no templates/<page_type>.json.

Limits

Style templates count toward the 600-file and 192 MiB package limits.

Install

Installing the theme from the Theme Store in a style sets every page up from that style's templates and applies its settings. The style is recorded on the installed theme.

Updates

An update never replaces a merchant's pages. A page the new version adds, and a page an update has to set up again because its sections were removed, come from the installed style's templates in the new version.

Editor

Choosing another style in the theme editor changes the theme settings only. The merchant's pages stay as they are.

Previews

The Theme Store demo of a style and the theme tools preview with --preset render the style's templates with its settings and demo overlay.

Optional capabilities#

Capability

Rule

Theme blocks

Each blocks/.vasc file declares kind block, compiles independently, and has the same name as its filename.

Global settings

config/settings_schema.json uses the global settings schema. Theme presets require this file.

Theme styles

Each config/presets file is a theme style: a name and a set of whole-theme setting values, and optionally its own page templates in templates/styles/. It is not a section preset catalog, and every value must pass the global settings schema.

Metafields

config/metafields.json may declare up to 40 storefront-readable definitions. Installation adopts a matching definition or creates it; a conflicting existing type blocks installation.

Locales

For every locale namespace the package includes, the matching file for default_locale is required.

Demo content

Any demo style must match a config/presets preset. Demo images and style overlays require demo/catalog.json.

Development imports and marketplace themes#

A direct store import may be partial so you can develop one surface at a time. A marketplace version must pass the sealed-theme checks: it ships a non-empty template for every theme-editable platform surface and handles canonical product and cart prices, including tax_display status. The sealed artifact is validated again when it is installed or updated.