メインコンテンツへスキップ

言語対応は片方向だった

日本語3ページを直し、日英6ページで確かめた記録

公開日:
みみやこでIT編集部
i18nSEONext.jsテスト開発記録
hreflangと書かれた端末風の枠の中で、jaとenの二つのページが双方向の矢印で結ばれた図。日英の対応関係を表す比喩です。

「みやこでIT」のサイトには、日本語ページと対になる英語ページがあります。検索エンジンにその対応を伝えるのが、HTMLのheadに出すhreflangの指定です。2026年10月31日の点検で、日本語の5ページがこの指定を出していないことが分かりました。本稿で扱うのは、そのうち修正した3ページです。英語ページの側は日本語ページを指しているのに、日本語ページの側からは英語ページを指していない。対応関係が片方向になっていました。

ここでは、その不具合をどう確かめ、どこを直し、本番で何を確認したかを記録します。変更はPR #382で、2026年11月2日に本番へ反映しました。検索流入や参加への効果は、まだ測っていません。

見つかった場面

きっかけは、検索まわりの施策を追跡しているIssue #349での公開ページの点検です。10月31日に日英の主要22URLを取得し直すと、すべてHTTP 200で、titleとdescriptionもそろっていました。一方で、日本語の5ページはheadのhreflangが0件で、対応する英語ページは各3件を出していました。

PR #382で直したのは、そのうち次の3組です。

日本語ページ英語ページ
/sponsor/en/sponsor
/faq/en/faq
/guides/kyoto-mokumoku/en/guides/kyoto-mokumoku

英語側はja・en・x-defaultの3つを出し、日本語側はcanonicalだけ。同じペアなのに、片方だけが「対になるページがある」と伝えていました。サイトのi18n設計でも、片側だけのhreflangは禁止しています。

修正前は英語ページだけが日本語ページを指し、修正後は日英が互いを指す(/faqの例)
修正前は英語ページだけが日本語ページを指し、修正後は日英が互いを指す(/faqの例)

原因はページごとの直書き

サイトには、canonicalとhreflangをまとめて組み立てる共通関数 buildAlternates があります(lib/i18n/metadata.ts)。英語ページはこの関数を通していました。ところが3つの日本語ページは、古い書き方のまま、canonicalだけを直接書いていました。

関数の動きは次のとおりです。

  • 日本語と英語の絶対URLを組み立て、表示中の言語のURLをcanonicalにする
  • 英語版の全体公開フラグが無効か、対象ルートが英語の品質確認を通っていなければ、canonicalだけを返す
  • 公開の条件を満たすときは、ja・en・x-defaultの3つを返す。x-defaultは日本語URL

公開してよいかの判定を関数の中に集めてあるので、ページ側でhreflangを手書きする必要はありません。直書きのページだけが、この判定の外にありました。

変更は3ファイルとも同じ形

修正は、3つの日本語ページのmetadataを共通関数に置き換えることです。FAQページの差分は次のとおりです(import行の追加を除く)。

  • 変更前 alternates: { canonical: "https://www.miyakodeit.com/faq" },
  • 変更後 ...buildAlternates("/faq", "ja"),

/sponsor と /guides/kyoto-mokumoku も、それぞれのパスで同じ置き換えをしました。本文、CSS、CTA、title、description、OGP、構造化データは変えていません。PR全体は6ファイルで、残る3つは回帰テスト、表示確認の記録、作業の学びを残すLEARNINGSです。

テストは実際のページ定義を読む

回帰テスト(__tests__/lib/reciprocal-hreflang.test.ts)は、共通関数だけを試すのではなく、日英それぞれのページファイルが実際にexportしているmetadataを読み込みます。関数が正しくても、ページが使っていなければ不具合は残るからです。

検査は1組につき2条件、3組で計6ケースです。

  • 英語公開がONのとき、日本語ページと英語ページが、それぞれ自分自身のcanonicalと、まったく同じja・en・x-defaultの組を出す
  • 英語公開がOFFのとき、どちらもcanonicalだけを出す

修正前のソースに戻して同じテストを実行すると、公開ONの3ケースがhreflangの欠落で失敗し、公開OFFの3ケースは成功しました。修正後は6ケースすべてが成功しています。テストが通るだけでなく、この不具合を実際に検出できることを、失敗する入力で確かめました。

本番での確認

PR #382は、次の順で受け入れました。

段階結果
通常CI(run 41388441020)SUCCESS。型・unit・i18n・デザイン・ビルド後のヘッダー回帰・イベント一覧の表示監査を含む
正式な独立QCPASS。指摘0件
merge2026年11月2日 13:34:22(日本時間)にsquash merge
本番HTML(13:36:25)日英6URLすべてHTTP 200、自己canonicalが1つ、ja・en・x-defaultが相互に一致、noindexなし。6/6 PASS
イベント表示の本番監査pnpm audit:events:production が終了コード0
公開後の統計整合CI(run 41389308221)SUCCESS

HTTP 200が返るだけでは、反映の証拠になりません。headに出ているcanonicalとhreflangそのものを、6URLすべてで読みました。

まだ分かっていないこと

確認できたのは、実装、テスト、CI、独立QC、本番HTMLまでです。次のことは、まだ分かっていません。

  • 検索エンジンがこの対応関係をいつ、どう扱うか
  • 検索の表示回数やクリック、英語ページからの参加や相談が増えるか

これらは公開後に同じ長さの期間どうしで比べて確かめる予定で、今回の修正の成果には数えていません。

10月31日の点検では、/first-time と /contact の日本語ページもhreflangが0件でした。この2ページはPR #382の対象外で、2026年11月2日時点のmainのソースでも、日本語側はcanonicalだけを出しています。英語側は共通関数を通しているため、同じ片方向が残っています。別の作業で扱います。

同じ不具合を探すときは

英語版のあるサイトなら、次の手順で同じ片方向を見つけられます。

  • 日本語ページと英語ページの両方のHTMLを取得し、headのhreflangを数える。片方だけ0件なら片方向
  • canonicalやhreflangをページごとに直書きしている箇所を検索し、共通関数に寄せる
  • テストは共通関数だけでなく、実際のページ定義を読む。修正前に戻すと失敗することも確かめる

「みやこでIT」では、こうしたサイト改善の作業も記録として公開しています。似た作業を進めている方は、イベント一覧からもくもく会を探して、作業の続きを持ち込んでみてください。

🏷️このカテゴリ:コミュニティ運営

カテゴリ一覧

もくもく会・勉強会・交流会の運営ノウハウとケース。

AIにWebサイト改善を任せてわかった、テストが通っても残る問題

みやこでITのサイト改善で見つかった、料金条件の取りこぼし、HTML読み取り、日本語の改行。修正と反例テスト、本番確認までの実例を紹介します。

大阪から京都のもくもく会へ。一人で参加する休日の組み立て方

大阪から京都のもくもく会へ一人で参加する準備を、実際の開催案内を例に整理。会場までの経路、参加枠ごとの料金、作業の準備、帰宅までを考えます。

京都で、誰かと、何かをつくる。みやこでITが育てたい「出会いのその先」

京都のITコミュニティ「みやこでIT」が大切にする、人との出会いから生まれる学び、仲間、小さな挑戦。2019年から活動を続けてきた主宰が、これから育てたいコミュニティの価値を語ります。

AIエージェントのLTで「動いた」をどう証明するか|公開デモのPASS→FAIL→PASSを1枚にする

AIエージェント実践LT会の開催記録を起点に、Agent Role Contractsの公開デモの入力・期待結果・過去CIを使い、再現可能な発表の証拠の残し方を整理。

大光寺のもくもく会をヒントに、初対面の人へ「詰まり」を伝える4行メモ

大光寺のもくもく会#62を起点に、初対面の相手へ短時間で相談内容を伝える4行メモを提案。実際の活動記録と架空の練習例、未検証の効果を区別します。

「試したこと」をコードで外へ返す。Agent Role ContractsをOSSとして公開しました

Agent Role Contracts 0.5.0をnpm latestの安定版として公開しました。役割・権限・レビュー分離・作業範囲・引き継ぎの宣言を、実行前にどう検査するかを最小の例で紹介します。

「みやこでIT」がProgate BAR「関西のテックコミュニティを語ろう」に登壇します|9月29日・京都

2026年9月29日、Progate京都ハッカソンハウスで開催される「関西のテックコミュニティを語ろう」に、みやこでITから小長井 元が登壇します。関西のテックコミュニティ4団体が協力するLT会・交流会です。

AIエージェント分業を試す|ChatGPT・Claude Code・Codexの実践手順

ChatGPT、Claude Code、Codexを役割分担して使う開発フローを、個人開発やもくもく会で試せる形に再設計しました。タスク契約、実装、決定論的チェック、独立レビュー、人間の最終判断までを具体的な手順で整理します。

✍️この著者:みやこでIT編集部

著者ページ

京都のITコミュニティ「みやこでIT」運営チームによる共同執筆・運営記事。

AIにWebサイト改善を任せてわかった、テストが通っても残る問題

みやこでITのサイト改善で見つかった、料金条件の取りこぼし、HTML読み取り、日本語の改行。修正と反例テスト、本番確認までの実例を紹介します。

大阪から京都のもくもく会へ。一人で参加する休日の組み立て方

大阪から京都のもくもく会へ一人で参加する準備を、実際の開催案内を例に整理。会場までの経路、参加枠ごとの料金、作業の準備、帰宅までを考えます。

AIエージェントのLTで「動いた」をどう証明するか|公開デモのPASS→FAIL→PASSを1枚にする

AIエージェント実践LT会の開催記録を起点に、Agent Role Contractsの公開デモの入力・期待結果・過去CIを使い、再現可能な発表の証拠の残し方を整理。

大光寺のもくもく会をヒントに、初対面の人へ「詰まり」を伝える4行メモ

大光寺のもくもく会#62を起点に、初対面の相手へ短時間で相談内容を伝える4行メモを提案。実際の活動記録と架空の練習例、未検証の効果を区別します。

元お茶屋「たか橋」でもくもく会#63|約100年の町家でPCを開く

2026年9月20日10:30〜13:30の、みやこもくもく会#63 @たか橋。約100年前に建てられたと考えられる元お茶屋の二階建て町家で、畳の座敷にPCを広げる回です。建物の来歴と、会場となる部屋の特徴も紹介します。

クラフトビールを片手に12人で「信頼」を考える|第一原理酒場 #1 開催レポート

2026年9月18日、京都市北区の夏屋で「第一原理酒場 #1」を開催しました。運営を含め12名が集まり、信頼と信用の定義、何のために何をどう信頼するのか、アナログなコミュニティの価値、第一原理思考について、クラフトビールと料理を囲みながら話し合いました。

「みやこでIT」がProgate BAR「関西のテックコミュニティを語ろう」に登壇します|9月29日・京都

2026年9月29日、Progate京都ハッカソンハウスで開催される「関西のテックコミュニティを語ろう」に、みやこでITから小長井 元が登壇します。関西のテックコミュニティ4団体が協力するLT会・交流会です。

京都・大光寺でみやこもくもく会#62を開催|約10名がAI・IoT・開発に取り組む

2026年9月5日、京都市伏見区の大光寺で「みやこもくもく会#62 with Digital Nomad Kyoto」を開催しました。約10名が参加し、ITエンジニア、AI開発に着手したい人、IoTで試行錯誤する人などが、一つのテーブルを囲んで作業と交流を楽しみました。

コミュニティに参加する

京都でITエンジニア仲間を見つけたい方へ

「みやこでIT」では、京都のお寺・町家・大学などで、もくもく会や勉強会を毎月開催しています。

📊 Source data

本記事に登場する「7年・166回・652名」「お寺/町家会場での開催」等の数値は、 「みやこでIT」年次統計レポート(/community-stats) の一次データに基づきます。年別開催数・会場分布・イベント種別構成の集計を公開しています。

⛩️

LM-4無料配布資料

京都のお寺でコードを書く — 「みやこでIT」参加ガイドブック2026

7年166回運営の実績から整理した、初参加を成功させる実践ガイド

対象:京都のITエンジニア・転職検討者・勉強会初参加の個人

主催者が公開しているイベント告知画像(京都・下京区)申込受付中

11月4日(水)

今回のテーマは、普段なかなか接点のない人たちが集まったら、何か面白いことが生まれるかも? です。 地域でお店や事業、面白…

開催時間19:00〜21:00
開催エリア京都・下京区