◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-04-30中級

Claude Codeでフロントエンドのアクセシビリティ監査を自動化する — axe-coreとプルリクのコメント連携で運用に乗せる

リリース直前に後回しになりがちなアクセシビリティ監査を、Claude Codeとaxe-coreで仕組み化します。CLIから動かす土台づくり、スキルとしての登録、PreCommitフックでの漏れ防止、GitHub ActionsによるPRへの自動コメントまで、日々の運用に乗せる具体的なワークフローです。

claude-code132accessibilitya11yaxe-coreautomation55

「アクセシビリティ対応は大事」と分かっていても、リリース直前に監査が後回しになる現場は本当に多いです。私自身、個人プロジェクトを4本同時に動かしている中で、a11y(アクセシビリティ)チェックだけは何度も流してしまい、結果として後追いで地味な修正コストを払う羽目になりました。

ここではClaude Codeのスキルとフックを組み合わせて、「監査を後回しにできない仕組み」を作る具体的な手順を共有します。axe-coreというデファクトスタンダードのa11yランタイムを軸に、日常のプルリク作成のたびに自動でコメントが付く流れまで持っていきます。

なぜ「監査ツールを入れた」だけでは続かないのか

アクセシビリティ監査が形骸化する原因は、ツールの不足ではありません。ほとんどのプロジェクトはすでに何らかのlinterやテストを動かしています。問題は、結果が「読まれる場所」にないことです。

CIのログに警告が並んでも、PR画面を開いている人は気づきません。レポートをSlackに飛ばしても、すぐに別の通知に押し流されます。私の経験では、監査結果がプルリクのコメント欄に直接書かれるようになって初めて、毎回目に入る情報になりました。

Claude Codeを噛ませる狙いは2つあります。1つ目は、生のaxe-core出力をそのままぶつけるのではなく、「修正に必要な手数」を要約した日本語コメントに変換すること。2つ目は、フックとスキルを組み合わせて、ローカル開発中もコミット直前に同じチェックが走るようにすることです。

ステップ1: axe-coreをCLIから動かす土台を作る

最初にやることは、ブラウザを立ち上げずにaxe-coreを動かす環境の用意です。Playwrightを噛ませるパターンが一番安定します。

# 必要パッケージのインストール
npm install -D @axe-core/playwright playwright @playwright/test
npx playwright install chromium

次に、監査スクリプトを1つだけ用意します。これは「指定したURLをaxe-coreで走査してJSON出力する」だけのシンプルな役割に絞ります。複雑にすると保守できなくなるので、ここは敢えて素朴に書きます。

// scripts/a11y-audit.mjs
import { chromium } from 'playwright';
import AxeBuilder from '@axe-core/playwright';
import { writeFileSync } from 'node:fs';
 
const targets = process.argv.slice(2);
if (targets.length === 0) {
  console.error('Usage: node scripts/a11y-audit.mjs <url> [<url> ...]');
  process.exit(1);
}
 
const browser = await chromium.launch();
const page = await browser.newPage();
const results = [];
 
for (const url of targets) {
  await page.goto(url, { waitUntil: 'networkidle' });
  const r = await new AxeBuilder({ page })
    .withTags(['wcag2a', 'wcag2aa']) // まずはAA基準まで
    .analyze();
  results.push({ url, violations: r.violations });
}
 
await browser.close();
writeFileSync('a11y-report.json', JSON.stringify(results, null, 2));
console.log(`Found ${results.reduce((n, r) => n + r.violations.length, 0)} violations across ${results.length} pages.`);

期待する出力は、プロジェクト直下に a11y-report.json が生成されること、そして違反件数のサマリが標準出力に出ることです。CIでもローカルでもこのスクリプト1つで完結するようにしておくのが、後で運用が壊れにくいコツです。

ステップ2: Claude Code用のスキルとして登録する

次に、このスクリプトをClaude Codeから呼び出せるスキルにします。Claude Codeのスキルは「ある決まった目的のためにモデルが自律的に呼び出せる手順書」です。詳しい仕組みはClaude Codeカスタムスキル開発ガイドで紹介していますが、ここでは最小構成だけ書きます。

# .claude/skills/a11y-audit/SKILL.md
---
name: a11y-audit
description: "指定URLにaxe-coreでアクセシビリティ監査を実行し、違反を重要度順に要約する。トリガー: アクセシビリティ, a11y, 監査"
---
 
# 使い方
 
1. `npm run dev` が動いていることを確認する
2. `node scripts/a11y-audit.mjs http://localhost:3000` を実行する
3. 生成された `a11y-report.json` から違反を critical / serious / moderate / minor に仕分ける
4. critical と serious を最優先にし、各違反について「該当セレクタ」「WCAG項目」「修正方針」を1つずつ提示する
5. PR本文に貼れるMarkdownブロックとして整形する

ポイントは2つあります。1つはdescriptionに「トリガー」のキーワードを必ず含めること。これがないとClaude Codeはスキルを呼び出し判断ができません。もう1つは、最小限の手順だけを書き、判断のロジック(どれを「重要」とみなすか)はモデルに任せることです。スキルを書きすぎると、現場ごとの差異に対応できなくなります。

ステップ3: PreCommitフックで「漏れ」を防ぐ

ここまででローカル監査は走るようになりますが、コミット前に思い出して走らせるのは現実的ではありません。Claude Codeのフックを使って、コミットの直前に自動で監査を発火させます。フックの仕組み自体はClaude Code Hooks自動化ガイドで詳しく解説しているので、ここでは設定だけ載せます。

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "command": "node scripts/a11y-audit.mjs http://localhost:3000 || true",
        "description": "コミット前にa11y監査を実行(失敗してもコミット自体は止めない)"
      }
    ]
  }
}

|| trueを付けて意図的に「コミットを止めない」設計にしている理由は、a11y違反でコミットが詰まると開発者がフックを無効化してしまうからです。フックは罰ではなく、目に留まる仕組みとして設計するほうが、結局は長期的に効きます。違反があるときはClaude Code側でレポートが要約され、開発者の前に提示される。それで十分です。

ステップ4: GitHub ActionsでPRに自動コメントする

最後のピースは、PRが立ったタイミングで自動コメントを残す仕組みです。Claude Codeとの連携はClaude Code GitHub Actions自動化ワークフローで扱っていますが、ここではaxe-core部分だけ抜き出します。

# .github/workflows/a11y.yml
name: A11y Audit
on:
  pull_request:
    branches: [main]
 
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npx playwright install --with-deps chromium
      - run: npm run build && npm run start &
      - run: sleep 5 && node scripts/a11y-audit.mjs http://localhost:3000
      - name: Comment summary on PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const data = JSON.parse(fs.readFileSync('a11y-report.json', 'utf8'));
            const counts = data.flatMap(p => p.violations).reduce((acc, v) => {
              acc[v.impact] = (acc[v.impact] || 0) + 1;
              return acc;
            }, {});
            const body = [
              '## アクセシビリティ監査の結果',
              `- critical: ${counts.critical || 0}`,
              `- serious: ${counts.serious || 0}`,
              `- moderate: ${counts.moderate || 0}`,
              `- minor: ${counts.minor || 0}`,
              '',
              counts.critical || counts.serious
                ? '⚠️ critical / serious が残っています。マージ前に対応をお願いします。'
                : '✅ critical / serious レベルの違反はありません。',
            ].join('\n');
            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body
            });

このワークフローのよいところは、a11y-report.json がそのままアーティファクトとして残せることです。違反の生データを Claude Code から後で読ませて、リファクタの優先順位を決めるのにも使えます。

ありがちな落とし穴

実際に運用してみて引っかかったポイントを3つだけ共有します。どれも「最初に知っていれば30分は節約できた」というレベルのものです。

1つ目は、SPA のルーティングを正しく扱えないケースです。Playwright で goto() した直後に axe-core を回すと、クライアント側のレンダリングが終わる前に走査が始まり、誤検知が出ます。waitUntil: 'networkidle' を入れるだけで解消するので、最初から書いておくのが安全です。

2つ目は、CIランタイムの増加です。Playwrightのブラウザバイナリだけで200MB近くあり、毎回ダウンロードしているとCIが遅くなります。actions/cache@v4 でPlaywrightのキャッシュディレクトリを保存しておくと、2回目以降は劇的に速くなります。

3つ目は、minor / moderate の違反まで全部出すと圧倒される問題です。最初は critical / serious だけに絞ってコメントを出し、慣れてきてから段階的にレベルを下げるほうが、結果的に修正が進みます。これは linter 全般に言える話で、Claude CodeでESLint修正を安全に進めるワークフローでも触れている考え方と通じます。

監査を「個人の意識」から「仕組み」へ

アクセシビリティは、個人の意識に頼ると必ず後回しになります。逆に、目に入る場所に結果が出てくる仕組みさえ作れば、半年後の自分が同じ違反を繰り返すことはなくなります。

私が今日伝えたかったのは、「監査ツールを入れる」と「監査を運用に乗せる」の間には大きな差があるということです。Claude Code はその差を埋めるためのとても素直な道具で、フック・スキル・GitHub Actions のどれかひとつでも導入してみると、感触がつかめると思います。

まずは scripts/a11y-audit.mjs だけでいいので、あなたのプロジェクトに置いてみてください。5分で動くはずです。動いたら、次は PreCommit フックを足して、最後に GitHub Actions に持っていく。この順番だと挫折しにくいです。

書籍で体系的に

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-04-30
Claude Code Skills を組み合わせる設計術 — 単一スキルでは届かない自動化を作る
Claude Code の Skills を1つずつ作るところから一歩進み、複数スキルを連携させて自動化を組む設計手法をお伝えします。Pipeline・条件分岐・メタスキルの3パターンとよくある落とし穴を実装例付きで詳述します。
⟐ Claude Code2026-03-28
Claude Code × Playwright で E2E テストを本番運用に乗せる — 落とし穴と導入の判断基準
Claude Code と Playwright を組み合わせて E2E テストを本番運用するための実装パターンと、導入効果の測り方。Cloudflare Workers/Pages preview deployment 下での落とし穴と、個人開発者がテストを導入する判断基準まで踏み込んで解説します。
⟐ Claude Code2026-03-24
Claude Code × unity-mcp でゲーム開発を自動化する方法 — 企画から公開までの完全ワークフロー
Claude Code と unity-mcp を組み合わせて Unity ゲーム開発を自動化する方法を解説。hcg-workflows スキルによる8フェーズワークフローで企画から公開まで効率化できます。