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

The theme check

The theme check reads a whole package in one pass and reports every problem at once. The same check gates a developer's release, the marketplace submission and the platform's own themes (a test runs it on every official theme). A theme with any error cannot be released or installed; warnings are what a reviewer reads first; an informational note is advice.

Every finding has a stable code (js.eval, section.unknown-block), the path it was found at, a message written for the developer and, where it can, a line number. The workspace groups findings by the code's first word — manifest, package, layout, template, section, block, setting, settings, presets, preset, liquid, snippet, asset, css, js, security, performance, locale, a11y, listing, docs, group, config — and re-runs on every save.

Manifest

Code Severity Rule
manifest.missing error every theme needs abizvo-theme.json at its root
manifest.json error it must be valid JSON
manifest.schema-version error schemaVersion must be 1
manifest.theme-api error themeApi must be 1.0
manifest.key error 2–40 lowercase letters, digits and hyphens, starting with a letter
manifest.name error required, at most 40 characters
manifest.version error major.minor.patch
manifest.developer error required
manifest.category error one of the thirteen categories
manifest.pages error / warning exactly one starter page is the home; each needs a name, a valid address and a template the theme has; none at all is a warning
theme.apps.unknown error apps.recommended or apps.required names an app key the platform does not have — an official app, or one the host's app store holds a released version of; a key nobody released would install nothing and recommend a blank
manifest.features warning the theme has JavaScript but does not declare features.javascript

Package and structure

Code Severity Rule
package.path error a path outside the ten folders, with .., absolute, too deep, or with an extension the platform does not serve
package.duplicate error two files at one path (compared exactly)
package.file-size, package.file-count, package.size, package.text-size error 10 MB per file, 1,500 files, 60 MB, 512 KB per text file
package.misplaced error a non-.liquid file in layouts, sections, blocks or snippets; a non-.json in templates or locales
layout.missing error layouts/theme.liquid
layout.header, layout.content error a layout must output {{ content_for_header }} and {{ content_for_layout }}
layout.title warning a <title> of the layout's own
template.missing error home, page and 404 templates
template.recommended warning contact and gallery templates
template.name error a template file not named for a type, or with a bad suffix
group.name error a -group.json not named header, footer, announcement, overlay or aside
group.missing warning no header or footer group
settings.missing error config/settings_schema.json
settings.json, settings.data-json, presets.json, template.json, group.json, locale.json error a config, template, group or locale file that is not valid JSON of the right shape
config.unknown warning a config file the platform does not read
listing.screenshots, docs.missing warning no screenshots/, no documentation/

Liquid

Code Severity Rule
liquid.parse error a layout, section, block or snippet Fluid cannot parse
liquid.schema-twice, liquid.stylesheet-twice, liquid.javascript-twice error a second {% schema %}, {% stylesheet %} or {% javascript %} in one file
section.name, block.name, snippet.name error a file name outside letters, digits, hyphens, underscores
section.schema-missing, block.schema-missing error a section or theme block without a {% schema %}
section.schema-json, block.schema-json error a schema that is not valid JSON
snippet.missing error {% render 'x' %} names a snippet the theme lacks
asset.missing error 'x' \| asset_url names an asset the theme lacks

Schemas

Code Severity Rule
settings.definition, setting.definition error a setting declaration that fails the rules on Settings: unknown type, bad id, a reserved id (size…), no label, no options, a bad range, an invalid default, responsive on a type that cannot be, a scheme group without a definition, a header or paragraph without content
settings.duplicate-id, setting.duplicate-id error two settings sharing an id in one owner
settings.schemes error more than one color_scheme_group
setting.scheme-group-place error a color_scheme_group anywhere but Theme settings
section.name-missing, block.name-missing error a schema without a name
section.block-duplicate, section.block-name error two local blocks of one type; a local block without a name
section.unknown-block, block.unknown-block error a named theme block the theme has no file for
section.max-blocks error max_blocks outside 1–250
section.placement error enabled_on / disabled_on naming a template type or group that does not exist
section.no-presets warning a section that cannot be added from the picker
section.category info no category for the picker
preset.name, presets.name error a preset or look without a name
preset.setting, preset.value, preset.block, presets.value error a preset setting a setting that does not exist, an invalid value, a block that cannot go there; a look with an invalid value

Data

Every template, group and settings_data.json is normalized against the theme's own schemas exactly as a site's saved data is at save and publish — every code on the Sections and blocks page (section.unknown, template.too-many-sections, block.not-accepted, block.limit, block.max, block.depth, block.children, template.layout, template.schema-version, setting.value, settings.value…). In a theme package, an informational note about a template (a value for a setting that does not exist) is raised to an error: a shipped file has no excuse.

Security

Code Severity Rule
security.remote-script error a <script src> from another site in any Liquid file
security.inline-handler error an inline event handler (onclick=…)
security.inline-script error an inline <script> with code (JSON and JSON-LD blocks are allowed)
security.script-url error an address that runs script: javascript:, vbscript:, or data: holding HTML or SVG
security.active-element error <base>, <object>, <embed>, a refresh <meta>, or a frame with srcdoc
security.svg-script error an SVG with a <script>, an on… handler or a javascript: link
security.svg-foreign error an SVG with <foreignObject>, <iframe>, <embed>, <object> or an external href
security.mime error a picture whose bytes are not the image its name says

CSS — read as tokens

Every .css asset and every {% stylesheet %} is tokenized by the platform's own CSS lexer, never matched as text, so a comment mentioning @import finds nothing.

Code Severity Rule
css.import error @import loads another stylesheet at runtime; put it in assets/ and link it
css.remote error / warning url(http:…) or url(//…) is an error; url(https:…) is a warning to review as a dependency
css.javascript error a javascript: address
css.script error expression() or behavior
a11y.focus warning outline: none (or 0) in a stylesheet with no :focus-visible rule

JavaScript — read as a syntax tree

Every .js and .mjs asset and every {% javascript %} is parsed with Acornima (a .mjs as a module; otherwise as a script, then as a module). A pattern match is never the evidence: every finding is a node of the tree, so a string that merely mentions eval finds nothing and window["ev" + "al"] is flagged. Unlike a site owner's generated effects, which run against an allowlist, a theme gets the whole DOM — so this is a denylist of the things no theme has a reason to do, the most dangerous refused outright and the rest flagged for the human review every marketplace release goes through.

Code Severity Rule
js.size error a script over 512 KB
js.parse error not valid JavaScript
js.eval, js.function, js.importscripts error eval, Function, importScripts run text as code
js.miner error a name of a known cryptocurrency miner
js.dynamic-import error import() loads code at runtime
js.remote-import error an import from another site
js.worker error new Worker / new SharedWorker
js.script-markup error a string literal containing <script
js.inject-script error document.createElement('script')
js.with error with
js.cookie error document.cookie — it holds the visitor's session
js.beacon error navigator.sendBeacon
js.credentials error the browser's credential store
js.document-write error document.write / writeln
js.string-timer error setTimeout / setInterval given a string
js.redirect error assigning location / href to a computed address or another site
js.form-action error assigning a form's action to a computed value
js.storage warning localStorage, sessionStorage, indexedDB
js.network warning fetch, XMLHttpRequest, WebSocket, EventSource
js.computed-global warning a member of window, globalThis, self or document reached by a name computed at runtime
js.html-sink warning innerHTML, outerHTML, insertAdjacentHTML
js.frame-reach warning window.opener, window.parent, window.top
js.inject-iframe warning document.createElement('iframe')
js.post-message-any warning postMessage(…, '*')
js.remote-src warning assigning an element's src to another site

Locales

Code Severity Rule
locale.name error a locale file not named for its language
locale.missing warning no locale file at all
locale.key-missing warning 'x.y' \| t with no text in the default locale (a plural key counts when it has other)
locale.french info no fr.json

Performance

Code Severity Rule
performance.css warning above 150 KB of CSS
performance.js warning / error above 150 KB of script; above 400 KB refused
performance.image warning one image above 800 KB
performance.size warning a package above 25 MB
performance.requests warning more than 60 assets

Accessibility

Code Severity Rule
a11y.lang warning <html> without lang
a11y.alt warning an <img> written by hand without alt — use image_tag, which writes the owner's alt text
a11y.new-tab warning a link opening a new tab without rel="noopener"
a11y.tabindex warning a positive tabindex
a11y.focus warning outline: none with no :focus-visible style

Reading findings in the workspace

Each save in the workspace re-runs the check and shows the report beside the file tree: the counts, then every finding under its category with its path and line. Release is refused while any error stands, with the count in the refusal. A finding's message says what to change; the code is what to search this page for.

The render also reports: a missing asset, a missing translation, a section that failed, an unknown form kind, a content_for outside a section. Those come back from the preview as render.* findings and never reach a visitor — a section that fails renders as nothing on the public page.

What the check does not do

It does not render every look and template, measure contrast, count H1s or read the sample content. Those are the premium theme standards, held by tests and by the human review rather than by the check.