Contact Form7の送信完了後にサンクスページへ遷移する方法(ページID不要)

Google reCAPTCHAの仕様変更、そして長年使ってきたMW WP Formについても変更するようにと通達もあったことから、Cloudflare Turnstile + Contact Form 7に切り替えることにした。
覚書メモ

ページID指定だと環境で壊れる

送信完了後に別ページへ飛ばす処理はだいたいこれを書くが、

add_action( 'wp_footer', function () {
    if ( is_page( 23 ) ) {
        ?>
        <script>
        document.addEventListener( 'wpcf7mailsent', function () {
            location = '/thanks/';
        }, false );
        </script>
        <?php
    }
} );

is_page(23) みたいにID直書きすると、ローカルと本番でページIDが違って動かなくなる…(あ…忘れてた😅とかね)
しかもエラーが出ず何も起きないだけなので、気づくのに時間がかかるとかw

ページIDを使わない書き方

ページの中身(CF7のショートコードがあるか)で判定すればID指定は不要になる。

add_action( 'wp_footer', function () {
    if ( is_singular() && has_shortcode( get_post()->post_content, 'contact-form-7' ) ) {
        $thanks_url = trailingslashit( get_permalink() ) . 'thanks/';
        ?>
        <script>
        document.addEventListener( 'wpcf7statuschanged', function ( event ) {
            if ( 'sent' === event.detail.status ) {
                location = '<?php echo esc_js( $thanks_url ); ?>';
            }
        }, false );
        </script>
        <?php
    }
} );
  • has_shortcode( $content, ‘contact-form-7’ ): 文字列に[contact-form-7 …]が含まれるかを見るだけの関数
  • get_permalink(): 表示中ページのURL

「お問い合わせページの直下にthanks/を置く」というルールさえ揃えておけば、他のサイトにもIDを書き換えずにそのまま使い回せる。

遷移トリガーのイベントは2通り書ける

送信完了を検知するイベントにはwpcf7mailsentとwpcf7statuschangedの2通りがあり、どちらでも同じようにリダイレクトを組める。

wpcf7mailsent版

document.addEventListener( 'wpcf7mailsent', function () {
    location = '<?php echo esc_js( $thanks_url ); ?>';
}, false );

wpcf7statuschanged版

document.addEventListener( 'wpcf7statuschanged', function ( event ) {
    if ( 'sent' === event.detail.status ) {
        location = '<?php echo esc_js( $thanks_url ); ?>';
    }
}, false );

wpcf7statuschangedは送信成功以外のステータス(invalid、spamなど)も同じイベントで拾えるので、送信失敗時の処理も併せて書きたい場合はこちらの方が扱いやすい。
単純に送信成功だけ検知したいならwpcf7mailsentでも問題ない。


・DOM events: wpcf7mailsent
・Form status(2023/12/17): wpcf7statuschanged