Skip to content

Svelte 5 ​

@a11y-hud/svelte is a Svelte 5 adapter using runes that mounts the a11y-hud Custom Element and re-runs axe after DOM updates.

Requirements ​

  • Svelte 5 (runes required)
  • a11y-hud (installed automatically as a dependency)

Install ​

bash
npm install --save-dev @a11y-hud/svelte
bash
pnpm add -D @a11y-hud/svelte
bash
yarn add -D @a11y-hud/svelte

Quick start — component ​

App.svelte
svelte
<script lang="ts">
  import { A11yHud } from "@a11y-hud/svelte";

  const isDev = import.meta.env.DEV;
</script>

{#if isDev}
  <A11yHud theme="auto" />
{/if}
<!-- rest of app -->

Quick start — hook ​

useA11yHud accepts a getter function (not a plain object) so Svelte's $effect can track reactive $props() values:

svelte
<script lang="ts">
  import { useA11yHud } from "@a11y-hud/svelte";

  const hud = useA11yHud(() => ({ theme: "auto" }));
</script>

Server-side rendering ​

Importing @a11y-hud/svelte is safe on the server (SvelteKit): the Custom Element is only registered when customElements exists. The HUD mounts in onMount, which runs only in the browser, so nothing is rendered server-side. You can place <A11yHud> in +layout.svelte without any browser guard.

Props / options ​

PropTypeDefaultDescription
themeTheme"auto"Visual theme
scopeElement | null—Element for scan scope (use bind:this)
autoScanbooleantrueRe-scan on DOM mutations
debouncenumber500Auto-scan debounce in ms
runOnlystring[]—axe rule tags to run

Scoping to a subtree ​

Use bind:this to get an element reference:

svelte
<script lang="ts">
  import { A11yHud } from "@a11y-hud/svelte";

  let appRoot = $state<HTMLDivElement | null>(null);
</script>

<A11yHud theme="auto" scope={appRoot} />
<div bind:this={appRoot}>
  <!-- only this subtree is scanned -->
</div>

Why a getter function for useA11yHud ​

Svelte 5's $effect tracks reactive reads that happen during execution. If you spread $props() into a plain object before passing it, the effect cannot track the individual reactive property reads. Passing a getter closure preserves reactivity:

ts
// ✅ reactive — $effect tracks reads through the closure
useA11yHud(() => ({ theme: props.theme }));

// ❌ not reactive — spread loses prop reactivity
const opts = { theme: props.theme };
useA11yHud(() => opts);

Route-change rescans ​

$effect fires after Svelte DOM updates, covering router-driven re-renders automatically. For explicit control, see the Route-change rescans cookbook.

Instance API ​

ts
const hud = useA11yHud(() => ({ theme: "auto" }));

hud.runScan()              // Promise<AxeResults | null> — null if not mounted yet
hud.setTheme("solarized-dark")
hud.setRunOnly(["wcag2a"])
hud.exportResults()
hud.ignores.add("color-contrast")
hud.ignores.list()

See UseA11yHudReturn for full type details.