Getting started
HTML-validate is an offline HTML5 validator.
Installation
Install using npm
:
npm install --save-dev html-validate
Create a configuration file:
{
"extends": ["html-validate:recommended"]
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
extends: ["html-validate:recommended"],
});
Run with:
npm exec html-validate yourfile.html
If you use Prettier code formatter add the htm-validate:prettier
preset as well to avoid style related rules clashing with Prettier.
Learn more about configuration presets.
Configuration
Configuration can be added to:
.htmlvalidate.js
.htmlvalidate.cjs
.htmlvalidate.json
ESM configuration files are not currently supported.
For json
the JSON schema https://html-validate.org/schemas/config.json
can optionally be used:
{
"$schema": "https://html-validate.org/schemas/config.json",
"extends": ["html-validate:recommended"],
}
For js
and cjs
the defineConfig(..)
helper can optionally be used to assist the IDE with type-checking and documentation:
import { defineConfig } from "html-validate";
module.exports = defineConfig({
extends: ["html-validate:recommended"],
});
Configuration files will be searched from the target file and up until either no more parent folders exist or "root": true
is found.
extends
Configuration can be extended from bundled preset or shareable configurations.
{
"plugins": ["my-plugin"],
"extends": [
/* bundled preset */
"html-validate:recommended",
/* npm package */
"my-npm-package",
/* preset "recommended" from "my-plugin" */
"my-plugin:recommended",
/* local file */
"./file",
],
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
plugins: ["my-plugin"],
extends: [
/* bundled preset */
"html-validate:recommended",
/* npm package */
"my-npm-package",
/* preset "recommended" from "my-plugin" */
"my-plugin:recommended",
/* local file */
"./file",
],
});
A list of bundled presets is available at the preset list.
By default html-validate:recommended
is used.
When using NPM packages or files each must be resolvable with require(..)
and export a valid configuration object.
Plugins may create configuration presets by exposing one or more preset in the plugin declaration.
rules
{
"rules": {
"some-rules": "severity",
"other-rule": ["severity", { "option": true }]
}
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
rules: {
"some-rules": "severity",
"other-rule": ["severity", { option: true }],
},
});
Severity can be one of:
"error"
(or2
) to report an error."warn"
(or1
) to report a warning."off"
(or0
) to disable the rule.
Some options takes optional parameters when using the form ["severity", OPTIONS]
.
See Available rules
for a list of all built-in rules and options.
elements
For proper validation some metadata for each element is required, detailing in
which context it can be used, allowed/disallowed attributes, etc. If elements
is not specified it defaults to ["html5"]
which is a bundled collection for
all HTML5 elements.
{
"elements": [
"html5",
"my-npm-package",
"./file.json",
{
/* inline metadata */
},
],
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
elements: [
"html5",
"my-npm-package",
"./file.json",
{
/* inline metadata */
},
],
});
Each entry will try to load metadata from (search in following order):
- Named bundled metadata.
- NPM package with the same name.
- A local file, json or js, resolvable by
require(..)
. Path is relative to the configuration file.
Loading native ESM is not supported yet (see issue #125) and must be transpiled to commonjs before usage.
An object can also be passed with inline metadata but it is highly recommended to write it to a separate file.
See elements metadata for details about writing your own metadata.
plugins
List of extra plugins to load. Plugins can contain additional rules, predefined configurations and transformers.
Can be either a NPM package or relative path to a local file, i.e. when writing custom rules inside the repository.
Must be resolvable by require(..)
.
See writing plugins for details about creating your own plugins.
{
"plugins": ["my-awesome-plugin", "./local-plugin"]
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
plugins: ["my-awesome-plugin", "./local-plugin"],
});
Loading native ESM is not supported yet (see issue #125) and must be transpiled to commonjs before usage.
Since version 7.17.0, if you are using javascript configuration or API you can also import or define plugins inline:
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
plugins: [
{
name: "my-awesome-plugin",
/* ... */
},
],
});
transform
Transform input files to extract HTML chunks, e.g. extract templates from javascript sources. See transformers for details.
{
"transform": {
"^.*\\.vue$": "html-validate-vue"
}
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
transform: {
"^.*\\.vue$": "html-validate-vue",
},
});
This will transform *.vue
with the html-validate-vue
NPM package.
Use a relative path to use a local script (use <rootDir>
to refer to the path to package.json
, e.g. <rootDir>/my-transformer.js
).
root
By default, configuration is search in the file structure until the root directory (typically /
) is found:
/home/user/project/src/.htmlvalidate.{js,cjs,json}
/home/user/project/.htmlvalidate.{js,cjs,json}
/home/user/.htmlvalidate.{js,cjs,json}
/home/.htmlvalidate.{js,cjs,json}
/.htmlvalidate.{js,cjs,json}
By setting the root
property to true
the search is stopped. This can be used
to prevent searching from outside the project directory or to use a specific
configuration for a specific directory without loading project configuration.
For instance, if /home/project/.htmlvalidate.json
contains:
{
"root": true
}
const { defineConfig } = require("html-validate");
module.exports = defineConfig({
root: true,
});
Only the following files would be searched:
/home/user/project/src/.htmlvalidate.{js,cjs,json}
/home/user/project/.htmlvalidate.{js,cjs,json}
This also affects CLI --config
and the API, e.g. when using --config
with a
configuration using "root": true
will prevent any additional files to be
loaded.
Inline configuration
Configuration can be changed inline using directive of the form:
<!-- [html-validate-ACTION OPTIONS -- COMMENT] -->
ACTION
is an action such as enable
, disable
etc and OPTIONS
is arguments to the action.
Comment is optional but encouraged.
Multiple rules can be enabled/disabled at once by using a comma-separated list:
<!-- [html-validate-disable-next void-style, deprecated -- disable both rules] -->
Comments can be entered using both --
and :
as delimiter:
<!-- [html-validate-disable-next deprecated -- justification for disabling] -->
<blink>Blinking text</blink>
<!-- [html-validate-disable-next deprecated: justification for disabling] -->
<blink>Blinking text</blink>
enable
<!-- [html-validate-enable element-permitted-content] -->
Enables a rule. If the severity is set to off
it will be raised to error
,
i.e a previously disabled warning will remain a warning after enabling it again.
disable
<!-- [html-validate-disable deprecated] -->
Disable a rule for the rest of the file or until re-enabled using enable
directive.
disable-block
<!-- [html-validate-disable-block attribute-allowed-values] -->
Disables a rule for a block of elements. All siblings and descendants following the directive will not trigger any errors.
<div>
<button type="foo">Invalid button</button>
<!-- [html-validate-disable-block attribute-allowed-values -- will be disabled until the parent div is closed] -->
<button type="bar">Invalid but ignored</button>
<button type="baz">Still ignored</button>
</div>
<button type="spam">Another invalid</button>
disable-next
<!-- [html-validate-disable-next deprecated] -->
Disables the rule for the next element.
<!-- [html-validate-disable-next deprecated -- the next occurrence will not trigger an error] -->
<blink>This will not trigger an error</blink>
<blink>But this line will</blink>
Ignoring files
.htmlvalidateignore
file
The .htmlvalidateignore
file works similar to .gitignore
, i.e. the file should contain a list of file patterns to ignore.
- Lines beginning with
#
are treated as comments - Lines beginning with
!
are negated patterns that re-include a pattern that was ignored by an earlier pattern. It is not possible to re-include a file excluded from a parent directory. - Paths are relative to the
.htmlvalidateignore
file
Similar to .gitignore
if a line starts with /
it matches from the current directory only, e.g /foo.html
matches only foo.html
in the current directory but not src/foo.html
.