Contact Form 7をREST API 経由でエラー415になった

React からREST API経由でContact Form 7 を利用していたのですが、エラーで415が返ってくるようになりました。

415は、以下のエラーとのこと。

HTTP 415 Unsupported Media Type クライアントエラーレスポンスコードは、ペイロードフォーマットがサポートされていないフォーマットであるため、サーバーがリクエストの受け入れを拒否することを示します

MDN

原因は何だったかと言うとContact Form 7 5.6に「REST API: フィードバック作成リクエストの Content-Type ヘッダーが multipart/form-data ではない場合に 415 HTTP エラーステータスを応答する。」というアップデートがあった為でした。

今までは、Content-Typeは、application/x-www-form-urlencodedとなっていました。ということで、修正後のコードがこちら。

  const handleSubmit = () => {

    const endpoint = process.env.REACT_APP_endpoint_contact
    const params = new FormData()
    params.append('yourName', name)
    params.append('yourEmail', email)
    params.append('yourMessage', message)

    const axiosConfig = {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    }

    axios
      .post(endpoint, params, axiosConfig)
      .then((res) => {
        setResMessage(res.data.message)
        setResStyle(res.data.status)

        if (res.data.status === 'mail_sent') {
          setName('')
          setEmail('')
          setMessage('')
        }
      })
      .catch((error) => {
        console.error(error)
      })
  }

参考ページ

https://reiji1020.hatenablog.com/entry/2018/12/31/113202

WordPress:REST API with Smart Custom Field

REST API

以前は、プラグインが必要だったREST APIですが、現行のWordPress5のcoreには、初めからREST APIが入っているようです。
今回、繰り替えしのフィールドが必要だったため、カスタムフィールドを登録するプラグインはSmart Custom Fieldを使用します。

カスタム投稿タイプとカスタムフィールドをREST APIに出力

カスタム投稿タイプをREST APIに出力するには、カスタム投稿タイプ作成時にREST APIに出力する設定が必要です。

function create_post_type() {
  $supports = [ 
    'title', // title
    'editor', // editor
  ];
  register_post_type( 'fruits', // 例:果物の場合
    array(
      'label' => '果物',
      'public' => true,
      'has_archive' => false,
      'menu_position' => 7,
      'supports' => $supports,
      'show_in_rest' => true, //rest api での取得有効にする
      'rest_base' => 'fruits' // rest api での取得名  /wp-json/wp/v2/fruits
    )
  );
}
add_action( 'init', 'create_post_type' );

REST APIの結果を確認してみましょう。

https://your-domain.com/wp-json/wp/v2/fruits

次にSmart Custom Fieldの値をREST APIに出力する設定を行います。
仮にSmart Custom Fieldに設定した名前が以下とします。

fruits_color テキストが入ります。
fruits_image idが入ります。

functions.phpに以下のコードを入力します。

// rest apiにカスタムフィールドを出力
add_action( 'rest_api_init', 'slug_register_fruits' );
function slug_register_fruits() {
  register_rest_field( 
    'fruits',   //フィールドを追加したいcustom投稿タイプを指定(先ほど登録したカスタム投稿タイプslugを指定)
    'fruits_meta',  // rest-apiに追加するキー
    array(
      'get_callback' => function( $object, $field_name, $request ) {
        // 出力したいカスタムフィールドのキーをここで定義
        $meta_fields = array(
          'fruits_color',
          'fruits_image',
        );
        $meta = array();
        foreach ( $meta_fields as $field ) {
          // バリデーションを一切してないので注意
          $meta[ $field ] = get_post_meta( $object['id'], $field, false ); // 第3引数はfalse、Smart Custom Fieldの繰り替えし機能を使うため
        }
        return $meta;
      },
      'update_callback' => null,
      'schema'          => null,
    )
  );
}

ここで注意して欲しいのが17行目のget_post_meta関数の第3引数です。
Smart Custom Fieldの繰り返しの機能を利用すると、繰り返されたグループの値は、カスタムフィールドに配列で格納されます。
そのため、第3引数にfalseを渡して、値を配列として受け取ります。
第3引数がtrueだと、繰り返されたグループの値が取得できません。

REST APIの出力結果を確認してみましょう。
カスタムフィールドの値が出力されているのが確認できると思います。

https://your-domain.com/wp-json/wp/v2/fruits

参考

wordpress rest-apiでカスタムフィールドを出力する際に処理結果を整形したい
https://qiita.com/kinshist/items/cd9f74af7db7c80746a1

React RouterのBrowserRouterがbuildの時、使えない

症状 create-react-appを使って、プロジェクトを作成・開発して、npm startした時は、正しくコンポーネントが描画されるのですが、npm run buildすると何も描画されず、真っ白な画面しか表示され … “React RouterのBrowserRouterがbuildの時、使えない” の続きを読む

症状

create-react-appを使って、プロジェクトを作成・開発して、npm startした時は、正しくコンポーネントが描画されるのですが、npm run buildすると何も描画されず、真っ白な画面しか表示されない現象に出くわしました。
その上、build時にはエラーは出ず、successしてしまうので原因の見当がつかず困りました。

環境

package.jsonのdependenciesは以下の通り。

"history": "^4.9.0",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-redux": "^5.0.6",
"react-router-dom": "^5.0.0",
"react-router-hash-link": "^1.2.1",
"react-router-redux": "^5.0.0-alpha.9",
"react-scripts": "^2.1.8",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0"

原因

ページの遷移にReact Routerを使っていたのですが、React Router V4からbuildする時には、BrowserRouterが使えないようで、これが原因でした。

この情報がなかなか見つけられず、骨が折れました。
解決できたのは、React学習用に買ったReact入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで にあったTipsに「GitHub PageにAppを公開する際は、BrowserHistoryだと動かない」という内容の記事を見つけて、試しにHashRouterに変更してbuildしたら動いたという幸運にめぐまれました。

React入門 にあったTipsをもう少し詳しく説明するとnpm startした時は、サーバが立ち上がり、どのようなURLのリクエストでもindex.htmlを返してくれる機能があるが、GitHub Pageではそのような対応をしてくれないため、Hash Historyを利用して、URLに「#」をつけて、ルートにあるindex.htmlを返すようにするということです。

このせいか、React Routerの仕様もBrowserRouterを使っていると機能しないようになっているのかもしれません。(本当のところは、わかりませんが。)

BrowserRouter使ってbuildしたい

HashRouterを使うとURLに「#」が入ってしまうのが、やっぱり気になります。少しだけ調べたのですが、Next.jsを使ってサーバーサイドレンダリングをする。もしくは、buildをreact scriptではなくwebpackを使ってバンドルしhistoryApiFallback を webpack.config.js に追加する方法があるようですが、まだ試していません。試した時は、また記事にしたいと思います。

参考ページ