HB DevTools

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 Actionapp/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 ComponentSeoAnalyzerClient.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を使った単体テストを実施しています。