Quality
@templatical/quality is the umbrella package for Templatical's template-quality tooling — deterministic, JSON-only linters that catch authoring mistakes inside the editor and in headless / CI checks. MIT-licensed, ESM, no Vue, no DOM.
Linters
| Linter | What it catches | Default severities |
|---|---|---|
| Accessibility | Missing alt text, low contrast, vague CTAs, heading-skip, undersized touch targets, ALL CAPS body, target=_blank missing rel, missing preheader, … | mostly error/warning |
| Structure | Duplicate block IDs, sections with the wrong column count, nested sections, empty sections, empty columns | mostly error; some warning |
| Links | Dangerous URL schemes (javascript:), unsupported protocols, malformed mailto: / tel:, staging / localhost URLs leaking into a template | mostly warning; link.javascript-protocol is error |
All three linters return the same LintIssue shape and share the same options surface (LintOptions) — so consumers can run them in any combination, merge results, and filter by ruleId prefix (a11y.*, structure.*, link.*) when grouping. Each linter's per-rule severities and tool-specific knobs live under its own namespace (accessibility, structure, links); set any of them to false to disable that linter entirely.
Architecture
The package has no opinion on UI. The editor's useTemplateLint composable lazy-imports @templatical/quality, runs every exported linter on debounced content changes, and merges results into a single issues stream that drives the Issues sidebar tab and the per-block canvas badges. applyFix(issue) runs each patch through the editor's existing block-update path so fixes land as proper undo entries.
Install
npm install @templatical/qualitypnpm add @templatical/qualityyarn add @templatical/qualitybun add @templatical/qualityThe package is an optional peer of @templatical/editor. Install it to turn on the Issues sidebar tab and canvas badges. Skip it and the editor stays lean — the dynamic import is gated and tree-shakeable, so the linter chunk never downloads.
CDN users
If you load Templatical via CDN, there's nothing to install. The editor's CDN bundle ships @templatical/quality as a separate code-split chunk that lazy-loads automatically when linting is enabled.
Wire into the editor
Pass lint to init() or initCloud():
import { init } from "@templatical/editor";
const editor = init({
container: "#editor",
locale: "en",
lint: {
accessibility: {
rules: {
"a11y.img-missing-alt": "warning", // soften from default 'error'
"a11y.text-all-caps": "off", // turn off entirely
},
thresholds: { minFontSize: 16 },
},
structure: {
rules: { "structure.empty-column": "info" }, // demote to info
},
links: {
rules: { "link.localhost-or-staging": "error" }, // promote before send
nonProductionHosts: ["*.staging.*", "*.preview.*"],
},
},
});The Issues tab and inline canvas badges appear automatically once the optional peer is resolved. When lint.disabled === true — or when every per-tool key (accessibility, structure, links) is false — the editor never lazy-loads the package: no chunk download, no UI surface.
Set any single linter to false to drop just that tool's rules:
init({ container: "#editor", lint: { links: false } });Quick links
- Options —
disabled,locale, per-toolaccessibility/structure/linksnamespaces. - Severity & fixes — severity model + how auto-fix patches land in the editor.
- Headless usage — validating stored templates in CI / server save handlers.
- Contributing locales — adding rule messages + vague-text dictionaries.
- Accessibility linter — what it catches, rule catalog.
- Structure linter — what it catches, rule catalog.
- Links linter — what it catches, rule catalog.