Vue A11y Community & Toolkit
raw JSON →Vue A11y represents a community-driven initiative focused on improving web accessibility within the Vue.js ecosystem. It is not a single, monolithic npm package but rather an umbrella organization (`@vue-a11y`) coordinating several specialized packages, tools, and guidelines designed to help developers build accessible Vue applications. Key projects under this umbrella include `@vue-a11y/announcer` for screen reader announcements, `@vue-a11y/skip-to` for keyboard navigation, `@vue-a11y/focus-loop` for managing focus traps, and `eslint-plugin-vuejs-accessibility` for linting a11y issues. While specific packages are actively maintained, the generic 'vue-a11y' name typically refers to the collective effort or an earlier, foundational concept that has since evolved into a modular approach. This modularity allows developers to pick and choose specific accessibility features as needed, supporting both Vue 2 and Vue 3 depending on the individual package. Release cadence varies per sub-package, but the community actively updates tools and resources to align with WCAG standards and Vue.js advancements.
Common errors
error Cannot find module 'vue-a11y' or its corresponding type declarations. ↓
@vue-a11y/* package you intend to use, e.g., npm install @vue-a11y/announcer or yarn add @vue-a11y/announcer. error ESLint: Rule 'vuejs-accessibility/heading-has-content' is not found. ↓
eslint-plugin-vuejs-accessibility is installed (npm install --save-dev eslint-plugin-vuejs-accessibility) and configured in your .eslintrc.js with extends: ['plugin:vuejs-accessibility/recommended']. Check the plugin's documentation for the correct rule names. error Screen reader does not announce dynamic content updates or route changes in my Vue SPA. ↓
@vue-a11y/announcer for dynamic announcements and ensure proper focus management. For route changes, use a skip link and programmatically set focus to the main content area or the page title. Warnings
breaking The generic `vue-a11y` package name (if it ever existed as a central installable library) is effectively deprecated and has been superseded by a collection of scoped `@vue-a11y/*` packages. Direct migration from a hypothetical `vue-a11y` v1.x to current versions requires installing specific scoped modules. ↓
gotcha Vue 2 and Vue 3 have distinct APIs and patterns, particularly for composition API vs options API and reactivity. Ensure that the `@vue-a11y/*` packages you install are compatible with your specific Vue version. For instance, `@vue-a11y/announcer` has separate branches/versions for Vue 2 and Vue 3. ↓
breaking `eslint-plugin-vuejs-accessibility` (a key `vue-a11y` tool) has seen updates to its rules and configuration. Older configurations or rule names might be deprecated or behave differently in newer versions, especially when migrating ESLint setups. ↓
gotcha Many accessibility features, such as focus management and ARIA attributes, require careful manual implementation even with dedicated libraries. Relying solely on components might not cover all edge cases or dynamic content changes, especially in Single Page Applications (SPAs). ↓
Install
npm install vue-a11y yarn add vue-a11y pnpm add vue-a11y Imports
- Announcer wrong
import Announcer from 'vue-a11y'; // Incorrect package name for componentscorrectimport { Announcer } from '@vue-a11y/announcer' - SkipTo wrong
const SkipTo = require('vue-a11y'); // CommonJS is usually not supported for modern Vue components; use ESM.correctimport { SkipTo } from '@vue-a11y/skip-to' - eslint-plugin-vuejs-accessibility wrong
import 'eslint-plugin-vuejs-accessibility'; // Not imported as runtime code; configured in ESLint.correctmodule.exports = { plugins: ['vuejs-accessibility'] }; // In .eslintrc.js
Quickstart
<!-- src/App.vue -->
<template>
<div id="app">
<Announcer assertive />
<nav>
<button @click="announceStatus('Navigating to Home...')">Home</button>
<button @click="announceStatus('Navigating to About...')">About</button>
</nav>
<main>
<h1>Welcome to the Accessible App</h1>
<p>{{ currentMessage }}</p>
<button @click="updateMessage">Update Status</button>
<input type="text" aria-label="Enter your name" placeholder="Your name">
</main>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { Announcer } from '@vue-a11y/announcer';
const currentMessage = ref('Initial content loaded.');
const announcer = new Announcer(); // For programmatic announcements
function updateMessage() {
const newMessage = 'Content updated successfully!';
currentMessage.value = newMessage;
announcer.polite(newMessage); // Announce politely to screen readers
}
function announceStatus(status) {
announcer.assertive(status); // Announce assertively
}
</script>
<style>
body { font-family: sans-serif; margin: 2rem; }
nav button, main button { margin-right: 10px; padding: 8px 15px; }
input { padding: 8px; margin-top: 15px; display: block; }
</style>