Contact Form 7でzipaddr-jpが動かなかった話|郵便番号→住所自動入力で踏んだid命名規則の罠

Contact Form 7 で zipaddr-jp が動かなかった話|郵便番号→住所自動入力で踏んだ id 命名規則の罠 Web Development
この記事は約16分で読めます。

受託で WordPress サイトの問い合わせフォームに「郵便番号を入れたら住所が自動で埋まるようにしてほしい」と依頼されることが、ここ数年で確実に増えました。Contact Form 7 で素朴に作ったフォームの郵便番号欄を、住所自動入力に対応させる依頼です。

WordPress.org でプラグインを検索すると、定番の zipaddr-jp がすぐに見つかります。Contact Form 7 にも対応していると公式ページに書いてあります。インストールと有効化、それから input の id を決まった名前にするだけ、という説明を読んで、私は「これは小一時間で終わるな」と思いました。

動きませんでした。郵便番号を入れても、住所欄は空のままです。エラーも出ません。原因は、地味な ── けれども作者本人が「誤って定義する方が多い」と注記しているくらい、誰もがハマる場所にありました。この記事では、その原因と回避策を、依頼を受けてから本番投入するまでの流れと一緒に書き残しておきます。

確認日:2026年5月8日。本記事の情報は、WordPress.org の zipaddr-jp プラグインページzipaddr-jp 公式サイトContact Form 7 公式サイトをもとにしています。
検証環境:Local by Flywheel / WordPress 6.9.4 / PHP 8.3.21 / Contact Form 7 ・ zipaddr-jp(いずれも2026年5月時点の最新版)。本番投入したクライアントサイトは2025年から稼働中で、月数十件の問い合わせが滞りなく送信されています。

クライアントからの依頼 ── Contact Form 7 で郵便番号→住所を

受けた依頼は、はっきりしていました。すでに Contact Form 7 で動いている問い合わせフォームに、郵便番号入力欄と住所欄を追加したい。郵便番号を入れると、都道府県・市区町村・町域までが自動で埋まるようにしてほしい。番地と建物名は、ユーザーが自分で入力する想定です。

WordPress を仕事で使っていると、似たような依頼に何度か出会います。問い合わせフォームの離脱率を下げたい、という運用上の動機がはっきりしているケースが多くて、自分の経験では「住所をユーザーに何度も書かせない」という設計のほうが、最終的なコンバージョンが地味に上がります。Google ドキュメントの問い合わせフォームではなく自前の WordPress サイトで完結させたい、というクライアントの意向もあって、そのあたりの体験を整える小さな改修でした。

とはいえ、「住所を自動入力する」という機能、自前で作ろうとすると意外と泥沼です。郵便番号と住所の対応データをどこから取るのか、データの更新はどうするのか、API を叩くなら通信失敗時のフォールバックはどうするのか。受託案件のスコープでこれを一から設計するのは、見積もりの何倍も時間がかかります。だから、ライブラリやプラグインの選定が実際の作業の半分以上を占めます。

WordPress でフォーム連携できるプラグインを探す

WordPress.org でプラグインを検索すると、郵便番号→住所自動入力で実用上の選択肢になるのは zipaddr-jp に絞られていきます。プラグイン作者の zipaddr-jp 公式サイト によると、Welcart、Contact Form 7、MW WP Form、Trust Form、WooCommerce、Ninja Forms、WP-Members、WPForms、Visual Forms Builder、JetFormBuilder と、主要な日本語フォームプラグインがほぼ網羅されています。

プラグインの仕組みは、シンプルで分かりやすい設計です。郵便番号の入力欄に値が入ると、プラグインの JavaScript がそれを拾って zipaddr 側のサーバーに jsonp 形式で問い合わせを送ります。返ってきた都道府県・市区町村・町域のデータを、フォーム上の対応する input に自動で書き込んでくれる、という流れです。

zipaddr-jp 動作シーケンス図

面白かったのは、対応フォーム一覧の「Contact Form 7 標準サポート」という記述。Contact Form 7 のフォームタグに、決められた id を付けるだけで連携できる、と書いてあります。たとえば郵便番号欄なら [text* your-postcode id:zip] のように、フォームタグの id オプションで zip を指定する書き方です。

「ID 規則を守れば動く」というシンプルな統合方式は、Contact Form 7 のように HTML 出力をフォームプラグイン側で組み立てるツールとの相性がよいです。HTML を直接書く案件で使う yubinbango.js のように form 要素や input のクラス名を細かく指定する方式は、Contact Form 7 では微調整がしにくいので、id 規則だけで完結する zipaddr-jp の設計は WordPress 側に寄り添っています。

zipaddr-jp を Contact Form 7 に組み込む

WordPress 管理画面でプラグインを検索してインストール、有効化。これで管理画面のサイドバーに「Zipaddr-JP」というメニューが追加されます。設定画面を開くと、郵便番号区切り文字、入力後にフォーカスを移動するか、プレースホルダーをどう書くか、といった項目が並んでいて、最初はどれもデフォルトのままで動きます。

続いて Contact Form 7 のフォームタグに id を仕込みます。私のフォームは、郵便番号・都道府県・市区町村・町域・以降の住所、と分けて入力させる構成だったので、こんな具合のマークアップになります(実際のラベル文言などは案件に合わせて調整しています)。

id 名は zip / pref / city / area / addr の5項目。これらが、郵便番号・都道府県・市区町村・町域・以降の住所、にそれぞれ対応します。zipaddr-jp は最大 6 グループまで同時利用できる設計になっていて、2 グループ目以降は zip2 / pref2 / city2 / area2 / addr2 と末尾に番号を付ける命名規則になっています。

id 命名規則対応表

ここまでの設定だけで、本来は動くはず ── というのが zipaddr-jp 公式ドキュメントの記述です。ただ、私はこの設定を一発で正しく書けず、最初の試運転で見事につまずきました。

動かなかった ── 何が起きていたか

プレビューで実際に郵便番号を入力してみました。「520-3041」と入れる。何も起きません。フォーカスを次の欄に移しても、住所欄は空のままです。

最初に疑ったのは、プラグインの読み込み失敗でした。ブラウザの開発者ツールを開いて、コンソールを確認します。エラーは出ていません。Network タブを見ると、zipaddr 側の API へのリクエストは飛んでいて、200 で返ってきています。レスポンスの中身を覗いてみると、ちゃんと「滋賀県」「栗東市」「出庭」のデータが入っています。

言い換えれば、プラグインは正しく動いている。郵便番号も拾えている。住所データもサーバーから返ってきている。なのに、フォームの input には何も書き込まれない。

こういう「途中までは正常、最後だけ無音」というケースは、たいていの場合、書き込み先の指定がずれています。プラグイン側がデータを書き込もうとしている input が、フォーム上に存在しないか、別の名前になっているか。私はこの時点で、フォームタグに付けた id を見直し始めました。

そして、自分のフォームタグを改めて読み返して、ようやく気づきました。

id を addr しか付けていない。

町域用の area が、丸ごと抜けていました。私は最初、「住所の自動入力」と聞いて、都道府県・市区町村・住所詳細の 3 つに分けるイメージで設計していました。pref / city / addr の 3 つで完結する、と思い込んでいたのです。

area 抜けの状態 vs 正しい状態

area と addr が分かれている理由

zipaddr-jp の areaaddr は、設計思想として役割がきっちり分かれています。

area は、郵便番号から特定できる「町域」の部分です。郵便番号「520-3041」を例にすると、ここに入るのは「出庭」です。zipaddr 側のデータベースは、都道府県・市区町村・町域までを返してくれますが、それより先 ── 番地や建物名・部屋番号 ── は、郵便番号からは特定できません。だから addr は、ユーザー自身が入力する欄として、別に用意されています。

言い換えれば、area は「自動補完される最後の input」、addr は「ユーザーが自分で書く最初の input」、というコントラクトです。両者を 1 つにまとめてしまうと、自動補完の結果と、ユーザー入力の番地・建物名が同じ input に同居することになって、補完のタイミングや値の置き換えで挙動が崩れます。

zipaddr-jp 公式ドキュメントの一番上に、「※この部分を誤って定義する方が多いようです」という注記が太字で書かれています。私は「ふんふん」と読み流して、id 命名規則のリストを 5 項目あることに気づかないまま、4 項目だけ書いていました。注記が太字で入っている時点で、本当は立ち止まるべきだったのですが、「インストールするだけで動く」というプラグインの謳い文句のほうに先に頭が引っ張られていたのだと思います。

area 用の input をフォームタグに 1 行追加し、町域は自動補完欄、番地・建物名はユーザー入力欄、と役割を分けたら、すんなり動きました。郵便番号「520-3041」を入れると、滋賀県 / 栗東市 / 出庭 が一瞬で埋まり、最後の番地欄にカーソルが移ります。クライアントにも気持ちよく使ってもらえる体験になりました。

Contact Form 7 のフォームタグ書式と zipaddr-jp id 規則のすり合わせ

動作確認用のチェックリスト

1 件の郵便番号で動いたからといって、すぐに本番投入してはいけない、ということを案件のたびに思い知ります。郵便番号と住所の対応には、思ったよりたくさんのエッジケースがあります。

本番投入の前に、私は最低限こんな郵便番号でテストするようにしています。

  • 政令指定都市の住所(例:「231-0023」横浜市中区山下町)。「市」と「区」の両方が住所に入るので、市区町村欄に「横浜市中区」と一気に入るか、それとも別の挙動になるかを確認します
  • 合併で住所表記が変わった市町村。zipaddr 側のデータが追従しているかを確認するために、最近合併した自治体の郵便番号を 1 つ入れてみます
  • 同じ郵便番号で複数の町域がある住所。一部の郵便番号は、複数の町域を指す(一致するものがない場合がある)ことがあります。zipaddr-jp はデフォルトで、データが一意に決まる範囲だけを自動入力する設計になっているので、複数候補のときの挙動を見ておきます
  • 北海道や東京都の特別区。「都」「道」が付く都道府県名の処理を確認します
  • 離島・遠隔地の郵便番号。沖縄や離島など、入力頻度の少ない地域の住所もデータに含まれているかを確認します

受託のサイトでは、こうした特殊ケースを数件まとめてテストして、すべてで自然に補完されることを確認してから引き渡しました。クライアントの問い合わせフォームでは想定読者の所在地に偏りがあるかもしれませんが、テストの段階では地理的な分布を意識して郵便番号を選んでおくと、本番投入後の「動かない」報告が減ります。

純 HTML / 純 JavaScript 環境では yubinbango.js

WordPress を使わない案件、たとえばランディングページや独立した申し込みフォームを HTML / CSS だけで組む場面では、yubinbango.js が定番です。私は受託で本番投入したことはなく、自作の HTML ページに組み込んで動作テストをした程度ですが、設置の手軽さは zipaddr-jp とは別系統の魅力があります。

yubinbango.js の特徴は、microformats(h-adr)の規格に沿ったクラス名で動くことです。フォーム要素に class="h-adr" を付けて、国名指定、郵便番号欄、都道府県・市区町村・町域・以降の住所、それぞれの input に決められたクラス名を振ります。class 名はこんな対応になっています。

  • p-postal-code ── 郵便番号
  • p-region ── 都道府県
  • p-locality ── 市区町村
  • p-street-address ── 町域
  • p-extended-address ── 以降の住所

WordPress と組み合わせるとき、Contact Form 7 や WPForms のようにフォームプラグイン側が HTML を組み立てる仕組みでは、class="h-adr" を form 要素に付けるのが意外と面倒です。プラグインによっては form 要素にクラスを追加するためのオプションがあったり、無かったりします。WordPress 案件では zipaddr-jp の id 規則のほうが扱いやすい、というのが私の感覚です。

逆に、WordPress を使わない静的 HTML や、フォームを自作している React / Vue 環境だと、yubinbango.js の microformats アプローチのほうがシンプルです。「フォームに 1 つクラスを付けるだけ」という設計の素直さが効いてきます。

触らなかった選択肢たち ── KEN_ALL.csv、zipcloud、postcode-jp

正直に書くと、今回の案件では他の選択肢を本格検討しませんでした。zipaddr-jp で要件が満たせるとわかった時点で深掘りはやめたので、以下は「触らなかったが存在を把握している」レベルの記述です。

KEN_ALL.csv は、日本郵便が公開している郵便番号データの公式 CSV です。これを自前でサーバーに取り込み、独自の検索エンドポイントを立てれば、外部サービス依存なしの実装ができます。データ量はそれなりにあって、月一回の更新を運用フローに組み込む必要が出てくるので、外部サービスへの通信を完全に避けたい、という強い要件がない限り、選びにくい選択肢です。

zipcloud は、無料で公開されている郵便番号検索 API です。GET 一発で住所が返ってくる手軽さが魅力ですが、運営者が個人で、サービス継続性の保証がない点が、本番投入の判断を難しくします。

postcode-jp は、商用の郵便番号 API サービスです。SLA や応答性能、サポート体制が整っていて、企業案件の選択肢としては有力ですが、料金プランが必要になります。

受託のクライアント案件では、追加の月額コストを発生させずに、WordPress 内で完結する zipaddr-jp がちょうどよい落としどころでした。エンタープライズ案件で、SLA が必須になる場面では、postcode-jp や類似の有料サービスが候補に上がってくると思います。

モバイル入力の最後の一手間 ── inputmode と autocomplete

住所自動入力が動くようになって、もう一段の体験改善を入れたくなりました。スマホで郵便番号を入力するとき、フリックキーボードのまま数字を打たせると、ユーザーの視線とタップ数が増えます。郵便番号の input には inputmode="numeric" を指定して、最初から数字キーボードが立ち上がるようにしておくと、入力の負担が下がります。

もうひとつ、autocomplete="postal-code" も合わせて指定しておきました。これはブラウザに「この input は郵便番号です」と教えるヒントで、過去にユーザーが入力した郵便番号を、ブラウザの保存値から自動補完してくれます。同じユーザーが何度か問い合わせるサイトでは、これが効きます。

Contact Form 7 のフォームタグでは、inputmodeautocomplete を直接書く構文がないため、こんな書き方で属性を追加しました。

Contact Form 7 のフォームタグでは、未知のオプション名を書いてもエラーにならず、HTML 属性として出力してくれる挙動があります。inputmode:numericautocomplete:postal-code は、それぞれ inputmode="numeric" autocomplete="postal-code" として最終的な input に反映されます。同じ要領で、各住所欄にも autocomplete="address-level1"(都道府県)、autocomplete="address-level2"(市区町村)、autocomplete="address-line1"(町域)、autocomplete="address-line2"(以降)を指定しておくと、ブラウザのオートフィル機能とも噛み合います。

都道府県・市区町村・町域は、zipaddr-jp が自動入力してくれるので、ユーザーがあえて手で入力するケースは少ないのですが、ブラウザのオートフィル候補が出ること自体に意味があります。「住所を覚えてくれているサイト」という体験は、フォーム送信のハードルを下げます。

本番投入後の体感

クライアントのサイトは2025年から稼働中で、月数十件の問い合わせがこのフォームから送信されています。住所自動入力が原因で問い合わせが止まった、という報告は、稼働開始から今までで一度もありません。zipaddr 側のサービスが万一止まっても、ユーザーが手で住所を入力すれば送信は通る作りにしてあるので、致命的な障害にはならない設計です。

体感として、住所入力のハードルが下がったことで「フォームに途中まで書いて諦める」という離脱が減ったという話を、クライアントから後日聞きました。具体的な数値までは追えていませんが、月数十件の送信が安定して続いているのは、フォーム周りの摩擦が小さくなった効果だと思います。

自分への戒め

今回の作業で改めて自分に言い聞かせたいのは、「公式ドキュメントの太字注記は、絶対に飛ばさない」ということです。zipaddr-jp 公式の「※この部分を誤って定義する方が多いようです」という一文。私はこれを読みながら、頭の中では「自分は気をつけるから大丈夫」と先送りしていました。結果、誤って定義する方の一人になりました。

「インストールするだけで動く」「設定不要」と書かれているプラグインでも、ID 命名規則のような小さなコントラクトは存在します。それを読み飛ばすと、API は動いていて、レスポンスも返ってきていて、エラーも出ない、という「途中までは正常、最後だけ無音」のデバッグに小一時間ほど吸い取られます。プラグインを過信しないこと、の前に、自分の読解を過信しないこと。これが今回の戒めです。

もうひとつ。areaaddr のように、設計上の理由で「自動補完される欄」と「ユーザー入力欄」が分けられているケースは、よく出会います。郵便番号と住所の関係に限らず、姓と名、メールアドレスと確認用メールアドレス、検索キーワードと絞り込み条件、といった「機械が埋める部分」と「人が埋める部分」を分けて設計するのは、自動化を扱うときの基本的な発想です。今回はそこを 1 つの input に押し込めようとしてつまずきました。次にライブラリを選定するときは、ライブラリの「データの流れ」と「ユーザー操作の流れ」を、フォーム設計に持ち込む前に分けて考える、という順序を徹底したいと思います。

同じく Contact Form 7 と zipaddr-jp の組み合わせで「動かない」とお悩みの方は、まず id 命名規則の area が抜けていないか、見直してみてください。私と同じ理由でハマっている可能性が、それなりに高いと思います。

同シリーズの記事として、フォーム周りの日本語入力体験についてもう一本書いています。「日本語入力の Enter でフォームが誤送信される問題を直した話|Safari・React・Vue 対応」も、Contact Form 7 を含む WordPress フォーム全般の参考になるかもしれません。

関連記事

本記事の情報は2026年5月8日時点のものです。zipaddr-jp や Contact Form 7 のバージョンアップにより、設定方法や対応フォームが変わる可能性があります。最新情報は、WordPress.org の zipaddr-jp プラグインページおよびzipaddr-jp 公式サイトで確認することをおすすめします。

コメント

タイトルとURLをコピーしました