• #seo
  • #nuxt
  • #cloudflare
未分類

概要

2025-10-25 現在、apps/web ディレクトリで運用している Nuxt Content(document-driven + MDX)サイトを対象に、Cloudflare Pages 配信を前提とした SEO の阻害要因を棚卸ししました。ここではクロール安定性、メタデータ一貫性、情報設計の 3 軸から課題を整理しています。

主要課題

  1. グローバル head 設定の破損
    apps/web/nuxt.config.ts 内の app.head が途中で文字化けしており、SSR HTML の <title><meta> が欠落。クローラが規定タイトル/description を取得できず、useSeoMeta フォールバックも発火しない。
  2. トップページの SSR エラーと文字化け
    apps/web/app/pages/index.vue のテキストおよび useSeoMeta 引数が Shift_JIS 風の破損データになり、閉じタグ抜けを引き起こしてビルド失敗や TTFB 低下を招いている。
  3. 動的ページのメタ不足
    apps/web/app/pages/[...slug].vue は title/description/OG のみで、canonical、article:published_timearticle:tag、構造化データ(JSON-LD)が未実装。記事として扱われず検索結果で競争力を失う。
  4. ナビゲーションの a11y & 意味論的欠落
    apps/web/app/components/Breadcrumb.vue では aria-labelaria-current が途中で切れ、パンくずを適切に解釈できない。内部リンクのアンカーテキスト評価にも悪影響。
  5. コンテンツ取得の非効率
    トップ/ディレクトリページ双方で queryCollection('pages').all() 後に手動フィルタしており、件数増に伴ってレスポンスが悪化しクロールバジェット消費が増大。
  6. robots / sitemap の未整備
    apps/web/public/robots.txt は Allow のみで sitemap 記述がなく、nitro.prerender.routes でも sitemap.xmlfeed.xml を生成していないため、重要 URL への案内が不十分。

推奨アクション

  • nuxt.config.tsindex.vue を UTF-8 (BOM なし) で再保存し、pnpm lint/pnpm test で構文チェック。app.headdefineNuxtConfig から一貫して管理する。
  • ページ共通の SEO ヘルパー(例: apps/web/app/utils/seo.ts)を新設し、useSeoMetadefinePageMeta + composable 化。canonical、OGP、twitter:cardarticle: 系をまとめて注入する。
  • DocPage.vue で記事 frontmatter を JSON-LD (Article, BreadcrumbList) に変換し、<script type="application/ld+json"> を挿入。クラウドフレア SSR 出力でダブルエスケープしないよう useHeadscript を利用。
  • Breadcrumb.vuearia-label="パンくずリスト"、最終要素の aria-current="page" を追加し、<nav> + <ol> 構造へ更新。アクセシビリティ lint (eslint-plugin-vuejs-accessibility) の導入も検討。
  • queryCollectionselect(['_path','title','description','publishedAt']) 等で必要最小限を取得し、wheresort を利用。よく呼ばれるリクエストは cachedFunction で 5〜15 分キャッシュ。
  • @nuxtjs/sitemap@nuxtjs/robots を追加し、nuxt.config.tssite.url を単一箇所に定義。Cloudflare Pages では npx wrangler pages dev で sitemap/robots を検証し、robots.txt から Sitemap: https://example.com/sitemap.xml を指す。

次のステップ

  1. 文字化けファイルの洗い出し → rg -Ul "[\x80-\xFF]" apps/web -g "*.vue" で異常バイトを検出し、一括で UTF-8 へ再エンコード。
  2. SEO ヘルパーと JSON-LD 実装を追加 → DocPage.vueTableOfContents.vue など共通コンポーネントへ順次適用。
  3. sitemap/robots 設定を行い、pnpm generate && npx wrangler pages deploy --dry-run でクラウドフレア配信を確認。
  4. 修正後に Search Console の URL 検査で再クロールを申請し、pnpm vitest --runInBand "seo" など軽量テストで回 regres を防止。

このメモはリグレッション可視化のため随時更新し、対応済み項目は日付付きで完了ログを追記してください。