はじめに
このブログは React ベースのフレームワークである Gatsby.js で構築していますが、ふとお問合せフォームの動作を確認したところエラーが発生していることに気が付きました。
今回の記事では、この原因と解決方法をまとめていきたいと思います。(Twitter ではなく X ですね…。)
原因調査
Gatsby.js で作成されているこのブログのお問合せフォームは、メール送信機能をサブドメインに設置した WordPress の ContactFrom7 に頼っています。
ざっくりと以下の仕組みで実装しています。
- JWT Authentication for WP-API というプラグインを WordPress 側にインストールし REST API 認証機能を追加
.env
に上記の認証情報を記述し、Gatsby.js 側でビルド時に認証情報を取り込む- コンタクトフォームのコンポーネントアクセス時に認証情報を送信。成功すればメールを送信できる状態になる
- 取得したトークンとフォームの情報を axios で送信する
この機能を実装した際は特に問題なくメールの送信は出来ていました。
API の通信に問題があるのではないかと思い、ブラウザのディベロッパーツールを確認したところ以下のようなレスポンスが返ってきていました。
👀「適正なユニットタグがありません?なんじゃこりゃ…。」
調べて見ると ContactFrom7 5.8.7 から、REST API でフォームを使用する際に正しいユニットタグが含まれていない場合、400 Bad Request を返すようになったことが原因のようです。
ユニットタグが何なのかは上記のリリースノートでは明言されていませんが、フォームを構成するフィールドのようです。
このバージョン以降は、REST API 経由で ContactFrom7 を利用した場合、フォームの構成要素であるユニットタグを含める必要があります。
ユニットタグの確認方法
じゃあユニットタグってどこを確認すればよいの?と思ったのですが、フォーラムに以下のような情報がありました。
ユニット・タグは次のようなコードです: wpcf7-f123-p456-o1
ユニット タグはページ内でユニークでなければならず、ラッパーの
の id 属性値に使用されます。また、_wpcf7_unit_tag フォーム・フィールドを通して送信されます。
Please help with REST API not work
一旦をフォームを設置して確認する必要がありそうなので、フォームを作成・設置後ブラウザのデベロッパーツールからユニットタグを確認します。
_wpcf7_unit_tag
という name 属性の value に記述されている文字列がユニットタグになります。
この情報を.env
とcontact.jsx
に追記します。
JWT_AUTH_USER=xxxxxxxx
JWT_AUTH_PASS=xxxxxxxx
FORM_ID=xxxxxxxx
+ WPCF7_UNIT_TAG=xxxxxxxx
# その他環境によって分ける設定
// 省略
/**
* フォームでsubmitが発生した時の処理
*/
const changeFinishScreens = async () => {
setIsStep({
contact: false,
confirm: false,
finish: true,
});
const formData = new FormData();
formData.set('your-name', value['name']);
formData.set('your-email', value['email']);
formData.set('your-title', value['title']);
formData.set('your-message', value['text']);
+ formData.set('_wpcf7_unit_tag', process.env.WPCF7_UNIT_TAG);
const axiosConfig = {
headers: {
Authorization: `Bearer ${token}`
},
};
const response = await axios.post(`${WEBSITE_URL}/wp-json/contact-form-7/v1/contact-forms/${FORM_ID}/feedback`, formData, axiosConfig);
setServerResponse(response);
// 送信処理が終了したらローディング画面を消す
setIsLoading(false);
};
修正後、メールを送信してみます。
正しくメールが送信されている事が確認できました。
管理者側にも通知メールが届いていることを確認できました。
その他
本記事の内容と異なりますが、WordPress 側では現在メール送信 API しか提供していません。
そのため、トップページや投稿ページがあった場合に表示させない簡単なプラグインを作成しています。
<?php
/*
Plugin Name: Disable Homepage Get Access
Plugin URI:
Description: GETリクエストに対してカスタムの挙動を設定するプラグイン。
Version: 1.0
Author: H.Nishihara
Author URI: https://blog.hn-pgtech.com/
*/
add_action('template_redirect', 'custom_get_request_handler');
function custom_get_request_handler() {
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// すべてのGETリクエストに対してカスタムページを表示する
wp_die('このページはアクセスできません。', 'アクセス禁止', array('response' => 403));
}
}
有効化してページにアクセスすると以下のような内容が表示されます。
ユニットタグ確認時は無効化して値を確認しました。