Technical Docs
SEO Analyzer の設計
Server Actions によるCORS回避、node-html-parser を使ったサーバーサイドHTML解析、SEO判定アルゴリズムの設計を解説します。
1. 設計思想 — なぜこのツールが必要か
WebサイトのSEO状態を確認するには、通常はブラウザのデベロッパーツールを開いてHTMLソースを 読むか、専用の有料ツールを使う必要があります。 「URLを1つ入力するだけで、主要なSEO要素を一括チェックできる」ツールがあれば、 開発初期から本番前の確認まで、日常的なワークフローに組み込めます。
本ツールでは、メタタグ・見出し構造・構造化データ・OGP・ 解析タグの5カテゴリを「パス/警告/エラー」の3段階で評価し、 問題点と改善アドバイスをセットで提示します。単なる「ある/なし」の判定ではなく、具体的な改善方法を示すことを 重視した設計です。
2. 技術アーキテクチャ
SEO Analyzer は他のツールとは異なり、サーバーサイドでのHTTPフェッチが必要です。 ブラウザから別ドメインのURLへ直接アクセスすると CORS エラーが発生するためです。 この問題を Next.js の Server Actions('use server')で解決しています。
- Server Action(
app/tools/seo-analyzer/_actions/analyze.ts): Cloudflare Functions 上で実行され、対象URLへのフェッチとHTML取得を行います。 15秒のタイムアウトと適切なUser-Agentを設定しています。 - 純粋関数群(
src/lib/tools/seo-analyzer.ts): 取得したHTML文字列を受け取り、各カテゴリの解析結果を返す関数群です。node-html-parserを使ってサーバーサイドでDOMを操作します。 - Client Component(
SeoAnalyzerClient.tsx):useTransitionでローディング状態を管理し、Server Action の完了後に結果を描画します。
HTMLパーサーとして node-html-parser を採用しています。 本プロジェクトは Cloudflare Pages(Cloudflare Workers)にデプロイされており、 Server Actions は Edge Runtime 上で動作します。 Edge Runtime は Node.js API(Buffer・ストリーム等)をサポートしないため、 それらに依存する一般的なDOMライブラリは使用できません。node-html-parser は純粋JavaScript実装でNode.js APIに依存せず、 Edge Runtime でも安定して動作します。
3. ロジック解説
HTMLパースには node-html-parser(Node.js API 非依存の純粋JavaScript製HTMLパーサー)を使用します。parse(html) で取得したHTMLをパースし、 CSSセレクタで要素を抽出します。
- メタタグ判定:
root.querySelector('title')?.textContentでタイトルを取得し、 30〜60文字の推奨範囲をチェックします。meta[name="description"]は70〜160文字が推奨とされ、 範囲外の場合は「警告」を返します。 - 見出し構造:
root.querySelectorAll('h1, h2, h3, h4, h5, h6')を順番に取得し、h1の重複や見出しレベルのスキップ(例: h2の次にh4)を検出します。 - 構造化データ:
root.querySelectorAll('script[type="application/ld+json"]')で 全ld+jsonスクリプトを抽出し、JSON.parse()で妥当性を検証します。 パースに成功した場合はスキーマタイプ(@type)を表示します。 - 解析タグ判定:
root.querySelector('head')?.innerHTMLおよびroot.querySelector('body')?.innerHTMLに対して正規表現を適用し、gtag.js/googletagmanager.com/gtagの有無でGA4を、adsbygoogle.jsの有無でAdSenseを検出します。 さらに完全なHTML文字列から測定IDのパターン(G-で始まるID、ca-pub-で始まるID)を抽出します。
4. 制限事項と注意点
SEO Analyzer は外部URLへのHTTPフェッチを行うサーバーサイドツールです。 仕組み上、解析できないケースが存在します。事前に把握しておくことで、 誤った「エラー」の解釈を防ぐことができます。
- 認証必須ページ: ログインが必要なページや、 Basic認証で保護されたステージング環境のURLは解析できません。 サーバーサイドフェッチにはユーザーのセッション情報が引き継がれないためです。
- JavaScript SPAのみのページ: Next.js・Nuxt・SvelteKit 等の SSR/SSGフレームワークで生成された静的HTMLは問題なく解析できますが、 クライアントサイドのみでレンダリングされるSPAページはHTMLが空に近い状態で返るため、 メタタグ・見出し構造が正しく取得できないことがあります。
- robots.txt / クローラーブロック: サーバーが
User-Agentを判定してクローラーをブロックするサイトでは、 403 または別のステータスコードが返り、解析に失敗します。 - タイムアウト制限(15秒): サーバーレスプラットフォームの 制約上、フェッチのタイムアウトは15秒です。 応答の遅いサーバーや大容量ページではタイムアウトエラーが発生します。
- HTTPS / HTTP の扱い: 入力URLが
http://の場合、 そのままフェッチを試みます。サーバーがHTTPSへのリダイレクトを返した場合は リダイレクト先を自動的にフォローします。 ただし、自己署名証明書など無効なTLS証明書のサイトは解析できません。
5. 品質管理
SEO Analyzer は外部URLへのアクセスを伴うため、 純粋関数の単体テストに加えて Playwright による E2E テストを実施しています。
- UIフローテスト(
e2e/seo-analyzer.spec.ts): URL入力 → 解析実行ボタンのクリック → 各結果セクションの表示確認という 一連のユーザー操作フローを自動化しています。 - エラーハンドリングテスト: 無効なURL・アクセス不能なURL を入力した際に エラーメッセージが適切に表示されることを確認します。
- 純粋関数テスト:
seo-analyzer.tsの各解析関数(メタタグ判定・ 見出し構造解析など)に対してサンプルHTMLを使った単体テストを実施しています。