a11y/required-element · 必須要素
すべてのルートがプロジェクトの宣言する要素を含まなければなりません。合成されたルートで判定するので、レイアウトの <main> も数えます。
重大度: warning · カテゴリ: a11y
宣言駆動のルールで、ルール自身の意見はありません。何も宣言しなければ何もせず、すべてのルートが持つべきタグ(<main>、<h1>、<nav> など)を宣言すれば、それ無しで合成されたルートは、ツールがルート全体を見渡せる場合に検出になります(「モードの違い」を参照)。
チェック内容
各ルートの本文を、合成された形で: レイアウトチェーン、ページ、リポジトリ内の .svelte に解決できるすべてのコンポーネント、そして app.html の <body>(ソース解析)、またはプリレンダリングされた文書の <body>(ビルド)です。レイアウトや解決済みコンポーネントが供給する要素も数えます。だからファイル単位ではなくルート単位で判定します。+page.svelte 単体が <main> を持つことはまれです。
export default {
rules: {
'a11y/required-element': { options: { elements: ['main', 'h1'] } }
},
overrides: [{ route: '/docs/**', rules: { 'a11y/required-element': { options: { elements: ['nav'] } } } }]
};
elements は素のタグ名のリストです(先頭は英字、続けて英数字とハイフン。大文字小文字は区別しない)。セレクタ構文は config 読み込み時に拒否されます。route を持つ overrides エントリは、マッチしたルートに対してリストに追加します。
存在の判定は楽観的で、{#if} のどの分岐、{#each} 本体、snippet の中にあっても数えます。そして本文のルールです: <svelte:head> の内容は決して数えず(必須の <title> は seo/title-presence の仕事)、<template> の子も数えず(インスタンス化されるまで不活性)、<svelte:element> は this が何であれ数えません。
<!-- +layout.svelte -->
<nav>…</nav>
<slot />
<!-- +page.svelte、`main` を宣言している場合 -->
<h1>Title</h1>
<p>ここにもレイアウトにも main が無い。</p>
存在するはどんな世界でも安全な主張です。未解決のコンポーネントは要素を足すことしかできないので、宣言した要素がすべて存在するルートは、すべて解決したかどうかに関わらず pass します。無いはページ全体についての主張なので、要素についての世界が閉じているとき、つまりすべてのコンポーネントが解決し {@html} も <svelte:element> も無いときにだけ行います。世界が開いたまま宣言要素が無いルートは、何も出力しません。
モードによる違い
- レンダリング解析(Vite プラグインのビルド): 文書そのものが閉じた世界なので、存在も不在もすべてのプリレンダリング済みルートで報告されます。
- ソース解析(CLI、ダッシュボードの静的ベースライン): 存在はどこでも報告し、不在は要素について閉じたルートでだけ報告します。実アプリでは大半のルートが、リポジトリ内のファイルに解決できないコンポーネント(UI ライブラリ、アイコンなど)を少なくとも 1 つ合成しているため、それが解決されるまで不在が報告されるルートは少数です。spread 属性や式による
idは、このルールにとって世界を開きません。要素を隠せないからです。
検出は、ソース解析ではそのルートのページファイル、ビルドではプリレンダリングされた HTML ファイルに位置づけられます。ダッシュボードのライブ層はこのルールを評価せず、静的ベースラインの結果がそのまま残ります。
なぜ重要か
「すべてのページに <main> ランドマークがある」「すべてのページに <h1> が含まれる」は、デザインシステムが約束し、コードレビューが確認し忘れる類の構造的保証です。宣言すれば、その保証は慣習ではなく、合成されたルート上のスコアされ gate される検出になります。
修正方法
その要素をルートに、普通はルートが合成するレイアウトに加えるか、適用しないルートについて overrides エントリで宣言を絞ります。
無効化
ルートスコープの検出は suppressions ファイル(npx svelte-vitals --update-suppressions)で抑制するか overrides で絞れます。宣言を消すか、ルールごと無効化しても構いません。suppressions ファイルについて知っておくべき点が 1 つ: キーは id::route::location なので、複数の宣言要素を欠くルートはそれら全部が 1 つのキーに入ります。あるルートについて記録したエントリは、そのルートのすべての要素欠落を、後から欠落する別の要素も含めて抑制します。
export default {
rules: {
'a11y/required-element': 'off'
}
};