Vize

Accessibility core

Use these rules to check the basic accessibility information in a Vue template: image alternatives, link text, valid ARIA attributes, keyboard equivalents, and form labels. Start here when adding images, links, or inputs to a component.

For example, open form-control-has-label before adding an input: compare its Bad/Good examples, enable the rule with the shown Vite+ configuration, and run vp run lint. The complete accessibility guide explains the broader rule set.

Every rule on this page includes its purpose, prerequisites, configuration, and complete Bad/Good examples. Highlighted lines show the changes; copied code keeps the complete source. Each packet states its current support limits.

Rule Examples Purpose
a11y/alt-text Bad · Good Require alternative text for media elements
a11y/anchor-has-content Bad · Good Require anchor elements to have accessible content
a11y/anchor-is-valid Bad · Good Enforce valid href on anchor elements
a11y/aria-props Bad · Good Disallow invalid ARIA attributes
a11y/aria-role Bad · Good Elements with ARIA roles must use a valid, non-abstract ARIA role
a11y/aria-unsupported-elements Bad · Good Disallow ARIA attributes on elements that do not support them
a11y/click-events-have-key-events Bad · Good Require keyboard event handlers with click events
a11y/form-control-has-label Bad · Good Require form controls to have associated labels

All rules · Rule Options · ESLint migration map · Project checks · Attributes across components

a11y/alt-text

Require alternative text for media elements

Bad · Good

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": {
        "a11y/alt-text": "warn"
      }
    },
  },
});
vp run lint

Bad

The image submit control supplies only its image URL; it has no alt text describing the action.

<template>
  <input type="image" src="/submit.png" />
</template>

Good

alt="Submit search" gives the image control an accessible name that describes submitting the search.

<template>
  <input type="image" src="/submit.png" alt="Submit search" />
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/anchor-has-content

Require anchor elements to have accessible content

Bad · Good

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": {
        "a11y/anchor-has-content": "warn"
      }
    },
  },
});
vp run lint

Bad

The /settings link has no text or other naming content, so its destination has no accessible description.

<template>
  <a href="/settings"></a>
</template>

Good

The visible Settings text supplies content for the same destination link.

<template>
  <a href="/settings">Settings</a>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/anchor-is-valid

Enforce valid href on anchor elements

Bad · Good

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": {
        "a11y/anchor-is-valid": "warn"
      }
    },
  },
});
vp run lint

Bad

The first anchor uses # for an action; the second uses a JavaScript URL. Neither provides an ordinary navigation destination.

<template>
  <a href="#" @click="openPanel">Open panel</a>
  <a href="JaVaScRiPt:void(0)">Run action</a>
</template>

Good

A native button performs openPanel, while the remaining anchor has the real /docs/javascript-urls destination.

<template>
  <button type="button" @click="openPanel">Open panel</button>
  <a href="/docs/javascript-urls">JavaScript URL guide</a>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/aria-props

Disallow invalid ARIA attributes

Bad · Good

Default severity: error
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": {
        "a11y/aria-props": "error"
      }
    },
  },
});
vp run lint

Bad

aria-lable is misspelled and is not a supported ARIA attribute.

<template>
  <button aria-lable="Save changes">Save</button>
</template>

Good

The supported aria-label attribute supplies the button name.

<template>
  <button aria-label="Save changes">Save</button>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/aria-role

Elements with ARIA roles must use a valid, non-abstract ARIA role

Bad · Good

Default severity: error
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": {
        "a11y/aria-role": "error"
      }
    },
  },
});
vp run lint

Bad

datepicker is not a recognized ARIA role for this section.

<template>
  <section role="datepicker">...</section>
</template>

Good

The section uses the recognized dialog role and a label describing the date selection.

<template>
  <section role="dialog" aria-label="Choose a date">...</section>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/aria-unsupported-elements

Disallow ARIA attributes on elements that do not support them

Bad · Good

Default severity: error
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": {
        "a11y/aria-unsupported-elements": "error"
      }
    },
  },
});
vp run lint

Bad

The metadata element carries aria-hidden, although meta does not support ARIA attributes.

<template>
  <meta charset="utf-8" aria-hidden="true" />
</template>

Good

Removing the ARIA attribute leaves the charset declaration intact.

<template>
  <meta charset="utf-8" />
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/click-events-have-key-events

Require keyboard event handlers with click events

Bad · Good

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.

Checks non-interactive elements without an interactive role. Native buttons and elements with an interactive ARIA role are outside this rule's finding.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  lint: {
    vize: {
      "preset": "incremental",
      "rules": {
        "a11y/click-events-have-key-events": "warn"
      }
    },
  },
});
vp run lint

Bad

The non-interactive div has a click handler but no keyboard event handling.

<template>
<div @click="activate">Activate</div>
</template>

Good

A native button provides keyboard activation for the same activate handler.

<template>
<button @click="activate">Activate</button>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules

a11y/form-control-has-label

Require form controls to have associated labels

Bad · Good

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": {
        "a11y/form-control-has-label": "warn"
      }
    },
  },
});
vp run lint

Bad

The search input has no label identifying what the user should enter.

<template>
  <input type="search" />
</template>

Good

Wrapping the input in a label associates the visible Search text with the control.

<template>
  <label>
    Search
    <input type="search" />
  </label>
</template>

Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.

Implementation · All rules