Documentation Abizvo Sites themes Liquid, the theme check and the premium standard — written from the code that enforces them

Package layout

A theme is a set of files. Paths are normalized on the way in and anything that is not a legal theme path is refused before any of it is read, so nothing later has to wonder about ../, absolute paths or files outside the theme's own folders.

Path rules

Every path in a package must be:

  • forward slashes only, no leading slash, at most 200 characters;
  • no . or .. segment, no empty segment, no drive letter or :, no control characters, no leading or trailing space in a segment;
  • at most four levels deep;
  • inside one of the ten folders below (or the manifest alone at the root);
  • made of ASCII letters, digits, -, _, . and @;
  • ending in an extension the platform serves: .liquid, .json, .css, .js, .mjs, .svg, .md, .txt, .png, .jpg, .jpeg, .webp, .avif, .gif, .ico, .woff2, .woff, .mp4, .webm.

Files an operating system leaves behind — .DS_Store, Thumbs.db, desktop.ini, anything starting with ._ — are dropped rather than refused. Two files at the same path (compared exactly, so Hero.liquid and hero.liquid are two paths) are an error.

Size caps

Cap Value
Files in a package 1,500
Package 60 MB
One file 10 MB
One text file 512 KB
Liquid steps per page render 1,000,000
Liquid recursion per render 24

The ten folders

Folder Holds Rule
layouts/ theme.liquid and any other layout, as .liquid theme.liquid is required; a template names another layout with "layout"
templates/ {type}.json or {type}.{suffix}.json one of the template types below; home, page and 404 are required, contact and gallery recommended
sections/ {name}.liquid with a {% schema %}, and the five group files {group}-group.json names are letters, digits, hyphens and underscores, at most 64 characters
blocks/ {name}.liquid theme blocks with a {% schema %} same naming rule
snippets/ {name}.liquid, rendered with {% render 'name' %} a render naming a snippet the theme lacks is an error
config/ settings_schema.json, settings_data.json, presets.json, product_fields.json settings_schema.json is required; any other file here is a warning (config.unknown)
assets/ CSS, JavaScript, pictures, fonts, video addressed with asset_url, served content-hashed and cacheable for a year
locales/ en.default.json, fr.json, fr-CA.json … named ^[a-z]{2}(-[A-Z]{2})?$ with .default marking the fallback language
screenshots/ listing pictures a theme without any is warned
documentation/ README.md, IMAGES.md, SAMPLES.json … a theme without any is warned

A file of the wrong kind in layouts, sections, blocks, snippets, templates or locales (a .txt under sections/) is an error (package.misplaced).

abizvo-theme.json

The manifest says who made the theme, what it is and what it asks of the platform. It is read with snake_case property names, comments and trailing commas tolerated.

{
  "schemaVersion": 1,
  "themeApi": "1.0",
  "key": "starter",
  "name": "Abizvo Starter",
  "version": "1.6.0",
  "developer": "Abizvo",
  "category": "Starter",
  "description": "The official reference theme.",
  "documentationUrl": "https://example.com/docs",
  "supportUrl": "https://example.com/support",
  "industries": ["Business", "Professional Services"],
  "features": { "animations": true, "javascript": false, "galleries": true, "video": true, "forms": true, "dynamicSources": true },
  "pages": [
    { "name": "Home", "slug": "home", "template": "home", "home": true },
    { "name": "About", "slug": "about", "template": "page.about" },
    { "name": "Contact", "slug": "contact", "template": "contact", "showInNavigation": true }
  ]
}
Field Rule
schemaVersion must be 1
themeApi must be one the platform supports: 1.0
key the theme's handle: 2–40 lowercase letters, digits and hyphens, starting with a letter (^[a-z][a-z0-9-]{1,39}$). A key belongs to the product that first published it
name required, at most 40 characters
version a semantic version major.minor.patch, no pre-release; each part is a number (major and minor up to 999, patch up to 9999). A release requires the manifest's version to equal the draft's
developer required
category one of Photography, Portfolio, Business, Agency, Real Estate, Restaurant, Fashion, Jewelry, Beauty, Professional Services, Retail, Technology, Starter
description, documentationUrl, supportUrl, industries free text and a list of words for the listing
features animations (loads the motion runtime on every page even where no setting asks for it), javascript (a theme with script that does not declare it is warned), galleries, video, forms, dynamicSources
pages the pages a new site starts with: each needs a name, a valid slug, and a template the theme has; exactly one carries "home": true. A theme that lists none is warned, and a new site then starts with a home page only

config/settings_schema.json

An array of named groups, each becoming one panel of Theme settings in the editor:

[
  { "name": "Colors", "settings": [ { "type": "color_scheme_group", "id": "color_schemes", "label": "Colour schemes", "definition": [ … ], "role": { "background": "background", "text": "text" } } ] },
  { "name": "Typography", "settings": [ { "type": "font_picker", "id": "heading_font", "label": "Headings", "default": "fraunces" } ] }
]

Every setting id is unique across the whole file; two settings sharing one is an error. A theme has exactly one color_scheme_group, and it lives here — a scheme group inside a section's schema is an error. What each setting may declare is on Settings.

config/settings_data.json

The values the theme starts with, under current:

{ "current": { "heading_font": "fraunces", "page_width": 1280, "color_schemes": { "scheme-1": { "name": "Paper", "settings": { "background": "#fbfaf7", "text": "#1d1b17" } } } } }

Every value is normalized against the schema by the theme check (an invalid one is an error; a value for a setting the theme no longer has is noted and left out).

config/presets.json

The theme's named looks — an array of { "name", "description", "screenshot", "settings" }. Each look is a set of global setting values (colour schemes included) that the editor's Looks row applies in one step. A look without a name is an error; each value is checked like settings_data.json.

config/product_fields.json

The product custom fields the theme reads (COM-018) — an array of { "key", "label", "type", "options", "info", "category", "filterable" }. key is lowercase letters, digits and underscores, starting with a letter (what the theme reads as product.fields.{key}); type is one of text, textarea, richtext, number, measurement, select (with options), checkbox, date, url, color, image, product, product_list and list; filterable offers a select or checkbox field as a collection filter. Nothing is created from it on its own: once the theme is a site's live theme, Inventory → Product fields (and every product's page) offers the owner the fields the workspace does not keep yet, in one click. A malformed entry, an unknown type or a key offered twice is an error; at most 50.

[
  { "key": "condition", "label": "Condition", "type": "select", "options": ["Pristine", "Excellent", "Good"], "filterable": true },
  { "key": "provenance", "label": "Provenance", "type": "list" },
  { "key": "complementary", "label": "Pairs with", "type": "product_list" }
]

templates/{type}[.{suffix}].json

A template is a JSON document of sections in order. The suffix makes an alternate template (page.about, entry.news); it is 1–48 lowercase letters, digits, hyphens and underscores.

Template types: home, page, contact, service, portfolio, gallery, album, blog, article, entry, 404, search, custom, product, cart, collection, list-collections, password, customers. entry is a collection entry's own page (entry.json for every collection, entry.{handle}.json for one). product is a product's own page (/products/{handle}), drawn with the product global; a theme without product.json still has product pages — the platform draws them inside the theme's chrome. What each renders is on Templates and pages. cart is the cart page (/cart) on a site that sells, drawn from the cart global; paying stays the platform's checkout step. collection is a product collection's page (/collections/{handle}, /collections/all) drawn with the collection global, and list-collections the list of them (/collections) drawn from product_collections; a theme without them has no collection pages. blog and article are a blog's list and its posts (/{blog}, /{blog}/{post}). password is the storefront password page (usually with its own layouts/password.liquid). customers holds the account pages a theme may draw — ship them in Shopify's folder, templates/customers/login.json, account.json, order.json and addresses.json, which load as customers.login and so on.

{
  "schema_version": 1,
  "name": "About",
  "layout": "theme",
  "sections": {
    "hero": {
      "type": "hero",
      "settings": { "min_height": 86 },
      "responsive": { "mobile": { "min_height": 70 } },
      "blocks": {
        "title": { "type": "heading", "settings": { "text": "Tell your story", "tag": "h1" } },
        "actions": { "type": "buttons", "blocks": { "primary": { "type": "button", "settings": { "label": "Book a call", "link": "action:booking" } } }, "block_order": ["primary"] }
      },
      "block_order": ["title", "actions"]
    },
    "story": { "type": "rich-text", "disabled": false, "settings": {} }
  },
  "order": ["hero", "story"]
}
  • sections is keyed by id (letters, digits, hyphens, underscores, at most 64 characters); order lists the ids that render, in order. An id in order the template lacks is a warning.
  • A section's type names a file in sections/; an unknown type is an error, and a section placed where its schema's enabled_on / disabled_on forbids is an error.
  • disabled: true keeps a section in the template and leaves it off the page.
  • responsive holds tablet and mobile overrides of settings marked "responsive": true; any other screen name is noted and ignored.
  • blocks and block_order nest to a depth of 6; a block's static: true marks one the section's markup places itself with {% content_for 'block' %} (it can be edited and hidden, not removed or moved).
  • A section's reusable names a saved section of the site; the placement then renders the saved content and its own settings are ignored.
  • layout names layouts/{layout}.liquid (theme by default); a layout the theme lacks is an error. schema_version is 1; a higher one is an error ("written by a newer version of the platform").

Limits: 100 sections per template, 2,000 blocks per template, 250 templates per site, 50 reusable sections per site, names at most 80 characters.

Section groups: sections/{group}-group.json

The five groups a theme may declare and a layout may render with {% sections 'name' %}: header, footer, announcement, overlay, aside. A group file has exactly the template shape, with type set from its name:

{ "name": "Header", "sections": { "header": { "type": "header" } }, "order": ["header"] }

A theme without a header and a footer group is warned. Groups render inside <div class="ab-section-group ab-section-group--{name}" data-ab-group="{name}">.

locales/

A locale file is a JSON object of strings, nested by dots in the key the t filter reads ('sections.hero.read_more' | t). A plural key is an object with one and other, chosen by the filter's count argument. en.default.json is the fallback; fr.json is what a Canadian French site reads. A theme with no locale file is warned; one without fr.json gets an informational note; a key used in Liquid with no text in the default locale is a warning.

assets/

Everything a page loads: the theme's stylesheet, any script, pictures, fonts, video. {{ 'theme.css' | asset_url }} gives a file's content-versioned address; a name the theme does not have is an error at check time and renders as nothing. A picture whose bytes are not the image its name says is an error (security.mime). What the check reads in CSS, JavaScript and SVG is on The theme check; the budget is on Assets, motion and effects.

screenshots/ and documentation/

Neither is rendered on a site. Screenshots are the pictures the theme library and a listing show; documentation is what a buyer reads — a README.md naming every section and setting, an IMAGES.md with the provenance of every sample picture, and a SAMPLES.json the preview tool uses for sample galleries. A paid theme's requirements for both are on Premium theme standards.