Fast HTML linter written in Go with special handling for Go templates. Validates HTML for accessibility, best practices, and common mistakes.
Implements rules from html-validate.org.
go install github.com/toba/go-html-validate@latest# Lint files or directories
htmlint web/
htmlint index.html about.html
# Errors only (no warnings)
htmlint -q web/
# JSON output
htmlint --format=json web/
# Disable specific rules
htmlint --disable=prefer-aria --disable=no-inline-style web/
# Ignore files by pattern
htmlint --ignore="*_test.html" web/
# List available rules
htmlint --list-rules| Flag | Description |
|---|---|
-f, --format |
Output format: text (default), json |
-q, --quiet |
Only show errors, suppress warnings |
--no-color |
Disable colored output |
--ignore PATTERN |
Glob pattern to ignore (repeatable) |
--disable RULE |
Disable specific rule (repeatable) |
--list-rules |
List all available rules |
-h, --help |
Show help |
--config PATH |
Use specific config file |
--no-config |
Disable config file loading |
--print-config |
Print resolved configuration |
This tool uses the same configuration format as html-validate.
Create .htmlvalidate.json in your project root:
{
"$schema": "https://raw.githubusercontent.com/toba/go-html-validate/main/schemas/htmlint.schema.json",
"extends": ["html-validate:recommended"],
"rules": {
"no-inline-style": "warn",
"prefer-tbody": "off"
}
}The linter searches for .htmlvalidate.json in the target directory and parent directories.
"error"or2- Error (fails CI)"warn"or1- Warning"off"or0- Disabled
Enable htmx attribute validation:
{
"frameworks": {
"htmx": true,
"htmx-version": "2"
}
}| Option | Values | Description |
|---|---|---|
htmx |
true/false |
Enable htmx attribute support (default: false) |
htmx-version |
"2", "4" |
htmx version to validate against (default: "2") |
htmx-custom-events |
["event1", ...] |
Custom event names to allow in hx-on:* without warnings |
When htmx is enabled, htmx attributes are recognized as valid and won't trigger attribute-misuse errors. Additionally, the htmx-attributes rule will validate htmx attribute values.
Custom events: If you use custom events (e.g., SSE-pushed events), hx-on:myevent will produce an "unknown event" warning by default. Add event names to htmx-custom-events to suppress these warnings:
{
"frameworks": {
"htmx": true,
"htmx-custom-events": ["count", "notification", "status"]
}
}Event names are matched case-insensitively.
Supported attributes (htmx 2.x):
- Request:
hx-get,hx-post,hx-put,hx-patch,hx-delete - Targeting:
hx-target,hx-swap,hx-swap-oob,hx-select,hx-select-oob - Behavior:
hx-trigger,hx-sync,hx-boost,hx-confirm,hx-prompt - URLs:
hx-push-url,hx-replace-url - Data:
hx-vals,hx-headers,hx-params,hx-include,hx-encoding - Inheritance:
hx-disinherit,hx-inherit - Other:
hx-ext,hx-indicator,hx-preserve,hx-validate,hx-disable,hx-disabled-elt,hx-history,hx-history-elt,hx-request - Events:
hx-on:*patterns (e.g.,hx-on:click,hx-on:htmx:after-request)
htmx 4-only attributes (warn when htmx-version is "2"):
hx-action,hx-config,hx-ignore,hx-method,hx-optimistic,hx-preloadhx-status:*patterns (e.g.,hx-status:404):inheritedsuffix (e.g.,hx-boost:inherited)
Deprecated in htmx 4 (warn when htmx-version is "4"):
hx-disabled-elt,hx-disinherit,hx-history-elt,hx-request,hx-vars
Go template syntax is validated automatically when linting .gohtml, .tmpl, or any file containing {{ template delimiters. The following template-specific rules are enabled by default:
| Rule | Description |
|---|---|
template-syntax-valid |
Validates balanced {{ and }} braces, matched control structures (if/end, range/end, etc.), and proper trim marker syntax ({{- and -}}) |
template-whitespace-trim |
Suggests using trailing trim markers (-}}) on control flow actions alone on a line to prevent unwanted blank lines in rendered output |
These rules examine the raw template content before preprocessing, allowing them to catch syntax errors that would otherwise cause parser failures.
To disable template rules:
{
"rules": {
"template-syntax-valid": "off",
"template-whitespace-trim": "off"
}
}| Preset | Description |
|---|---|
html-validate:recommended |
All rules enabled (default) |
html-validate:standard |
Core rules, fewer style preferences |
html-validate:a11y |
Accessibility-focused rules only |
Create .htmlvalidateignore for gitignore-style patterns:
node_modules/
vendor/
**/*.generated.html
For full configuration options, see the html-validate configuration documentation.
.html.htm.gohtml.tmpl
area-alt-<area>elements must have alt textaria-hidden-body-<body>must not have aria-hiddenaria-label-misuse- aria-label only on interactive elementsbutton-name- Buttons must have accessible namesheading-content- Headings must have text contentheading-level- Heading levels must not be skippedhidden-focusable- Hidden elements must not be focusableimg-alt- Images must have alt attributesinput-label- Form inputs must have labelslink-name- Links must have accessible namesmeta-refresh- Avoid meta refresh redirectsmultiple-labeled-controls- Labels must reference single controlsno-abstract-role- No abstract ARIA rolesno-autoplay- Avoid autoplay on mediano-redundant-role- No redundant ARIA rolesprefer-native-element- Prefer native HTML over ARIArequire-lang-<html>must have lang attributesvg-focusable- SVGs must have focusable="false"tabindex- Avoid positive tabindex valuesunique-landmark- Landmark regions must be unique
attribute-allowed-values- Valid attribute valuesattribute-misuse- Attributes used correctlydoctype- Document must have DOCTYPEduplicate-id- IDs must be uniqueelement-name- Valid element nameselement-permitted-content- Valid child elementselement-permitted-occurrences- Element count limitselement-permitted-order- Correct element orderelement-permitted-parent- Valid parent elementselement-required-ancestor- Required ancestor elementselement-required-attributes- Required attributes presentelement-required-content- Required child contentno-dup-attr- No duplicate attributesno-dup-class- No duplicate classesvalid-autocomplete- Valid autocomplete valuesvalid-id- Valid ID syntaxvoid-content- Void elements have no content
deprecated- No deprecated elementsno-deprecated-attr- No deprecated attributesno-conditional-comment- No IE conditional comments
button-type- Buttons should have explicit typeempty-title- Title elements must not be emptyform-dup-name- Unique form control namesform-submit- Forms should have submit buttonslong-title- Avoid overly long titlesmap-dup-name- Unique map namesmap-id-name- Map id and name should matchno-implicit-input-type- Explicit input typesno-missing-references- Valid ID referencesno-multiple-main- Single main elementno-redundant-for- No redundant label forno-utf8-bom- No UTF-8 BOMprefer-aria- Use ARIA attributesprefer-button- Prefer button over inputprefer-semantic- Use semantic elementsprefer-tbody- Tables should have tbodyscript-element- Valid script elementsscript-type- Valid script typestel-non-breaking- Tel links with proper spacing
allowed-links- Validate link protocolsno-inline-style- Avoid inline stylesno-style-tag- Avoid style tagsrequire-csp-nonce- CSP nonce on scripts/stylesrequire-sri- Subresource integrity
htmx-attributes- Validates htmx attribute values (hx-swap, hx-trigger, hx-target, hx-on:, hx-vals, hx-headers, hx-include, hx-status:)
template-syntax-valid- Validates Go template syntax (balanced braces, control structures, trim markers)template-whitespace-trim- Suggests trim markers to prevent unwanted whitespace
MIT - See LICENSE for details.
Rule specifications derived from html-validate (MIT License).