HTML rules
Every rule on this page includes its purpose, prerequisites, configuration, and complete Bad/Good examples. Highlighted lines show what changes; copying an example gives you the complete source. Each rule also states its current support limits.
| Rule | Examples | Purpose |
|---|---|---|
html/deprecated-attr |
Bad · Good | Disallow deprecated HTML attributes |
html/deprecated-element |
Bad · Good | Disallow deprecated HTML elements |
html/id-duplication |
Bad · Good | Disallow duplicate element IDs |
html/no-consecutive-br |
Bad · Good | Disallow consecutive <br> elements |
html/no-dupe-style-properties |
Bad · Good | Disallow duplicate properties in inline style attributes |
html/no-duplicate-class |
Bad · Good | Disallow duplicate class names in a static class attribute |
html/no-duplicate-dt |
Bad · Good | Disallow duplicate <dt> names in <dl> |
html/no-empty-palpable-content |
Bad · Good | Disallow empty elements that expect visible content |
html/require-datetime |
Bad · Good | Require datetime attribute on <time> element |
All rules · Rule Options · ESLint migration map · Project checks · Attributes across components
html/deprecated-attr
Disallow deprecated HTML attributes
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/deprecated-attr": "warn"
}
},
},
});
vp run lint
Bad
The paragraph uses the deprecated presentational align attribute.
<template>
<p align="center">Notice</p>
</template>
Good
The class and text-align: center declaration express the alignment through CSS.
<template><p class="notice">Notice</p></template>
<style scoped>.notice { text-align: center; }</style>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/deprecated-element
Disallow deprecated HTML elements
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/deprecated-element": "warn"
}
},
},
});
vp run lint
Bad
The center element uses a deprecated HTML presentation element.
<template>
<center>Profile</center>
</template>
Good
A section and a styling class replace the deprecated element while preserving the content.
<template>
<section class="profile">Profile</section>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/id-duplication
Disallow duplicate element IDs
Default severity: error
Presets: essential, happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/id-duplication": "error"
}
},
},
});
vp run lint
Bad
Both the input and help paragraph declare id="email", so the label target is ambiguous.
<template>
<label for="email">Email</label>
<input id="email" />
<p id="email">Required</p>
</template>
Good
The input keeps email; the help paragraph uses email-help, and aria-describedby refers to that distinct ID.
<template>
<label for="email">Email</label>
<input id="email" aria-describedby="email-help" />
<p id="email-help">Required</p>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/no-consecutive-br
Disallow consecutive <br> elements
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/no-consecutive-br": "warn"
}
},
},
});
vp run lint
Bad
Two consecutive break elements create spacing between blocks inside a single paragraph.
<template>
<p>First line<br /><br />Second block</p>
</template>
Good
Separate paragraphs express the two content blocks without repeated break elements.
<template>
<p>First line</p>
<p>Second block</p>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/no-dupe-style-properties
Disallow duplicate properties in inline style attributes
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/no-dupe-style-properties": "warn"
}
},
},
});
vp run lint
Bad
Each static style repeats one property; margin and MARGIN also count as the same property.
<template>
<div style="color: red; color: blue">text</div>
<div style="margin: 0; MARGIN: 1px">text</div>
</template>
Good
The static style uses distinct color and background properties. Dynamic style bindings are outside this static-attribute check.
<template>
<div style="color: red; background: blue">text</div>
<div :style="{ color: a, color: b }">text</div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/no-duplicate-class
Disallow duplicate class names in a static class attribute
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/no-duplicate-class": "warn"
}
},
},
});
vp run lint
Bad
The static class list repeats the btn token.
<template>
<div class="btn btn primary">click</div>
</template>
Good
The class list keeps one btn token and the distinct primary token.
<template>
<div class="btn primary">click</div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/no-duplicate-dt
Disallow duplicate <dt> names in <dl>
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/no-duplicate-dt": "warn"
}
},
},
});
vp run lint
Bad
The same definition list repeats the API term for two descriptions.
<template>
<dl>
<dt>API</dt>
<dd>Public interface</dd>
<dt>API</dt>
<dd>Internal service</dd>
</dl>
</template>
Good
One API term is followed by both descriptions, avoiding the repeated term.
<template>
<dl>
<dt>API</dt>
<dd>Public interface</dd>
<dd>Internal service</dd>
</dl>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/no-empty-palpable-content
Disallow empty elements that expect visible content
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: See typed options and defaults.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/no-empty-palpable-content": "warn"
}
},
},
});
vp run lint
Bad
The paragraph, list item, and table cell all have empty palpable content.
<template>
<p></p>
<li></li>
<td></td>
</template>
Good
Text fills the paragraph, interpolation supplies the list item, and aria-label explicitly names the otherwise empty cell.
<template>
<p>Overview</p>
<li>{{ item.label }}</li>
<td aria-label="No value"></td>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
html/require-datetime
Require datetime attribute on <time> element
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"html/require-datetime": "warn"
}
},
},
});
vp run lint
Bad
The time element contains a human-readable date but no machine-readable datetime value.
<template>
<time>May 13, 2026</time>
</template>
Good
datetime="2026-05-13" supplies the corresponding machine-readable date.
<template>
<time datetime="2026-05-13">May 13, 2026</time>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.