---
title: a11y/required-element · 必須要素
description: すべてのルートがプロジェクトの宣言する要素を含まなければなりません。合成されたルートで判定するので、レイアウトの <main> も数えます。
---

**重大度:** warning · **カテゴリ:** a11y

宣言駆動のルールで、ルール自身の意見はありません。何も宣言しなければ何もせず、すべてのルートが持つべきタグ（`<main>`、`<h1>`、`<nav>` など）を宣言すれば、それ無しで合成されたルートは、ツールがルート全体を見渡せる場合に検出になります（「モードの違い」を参照）。

## チェック内容

各ルートの**本文**を、合成された形で: レイアウトチェーン、ページ、リポジトリ内の `.svelte` に解決できるすべてのコンポーネント、そして `app.html` の `<body>`（ソース解析）、またはプリレンダリングされた文書の `<body>`（ビルド）です。レイアウトや解決済みコンポーネントが供給する要素も数えます。だからファイル単位ではなくルート単位で判定します。`+page.svelte` 単体が `<main>` を持つことはまれです。

```js svelte-vitals.config.js
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` が何であれ数えません。

```svelte
<!-- +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 つのキーに入ります。あるルートについて記録したエントリは、そのルートのすべての要素欠落を、後から欠落する別の要素も含めて抑制します。

```js svelte-vitals.config.js
export default {
  rules: {
    'a11y/required-element': 'off'
  }
};
```
