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 |
Both 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.*) when grouping.
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: {
rules: {
"a11y.img-missing-alt": "warning", // soften from default 'error'
"a11y.text-all-caps": "off", // turn off entirely
"structure.empty-column": "info", // demote to info
},
thresholds: { minFontSize: 16 },
},
});The Issues tab and inline canvas badges appear automatically once the optional peer is resolved. When lint.disabled === true, the editor never lazy-loads the package — no chunk download, no UI surface.
Quick links
- Options —
disabled,locale,rules,thresholds(shared by every linter). - 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.