
Trustindexプラグインの脆弱性、認証なしでトークンが漏洩する問題と対策
Trustindexプラグインのトラブルシューティング用RESTエンドポイントが認証なしでアクセス可能になっていると、Instagram Graph APIのアクセストークンを含む全オプションが外部に漏洩する。HMAC署名のキーに公開情報を使っている設計上の欠陥が原因であり、修正パッチが配布されるまでの間はエンドポイント自体を遮断する応急処置が必要になる。
何が起きているのか 〜 脆弱性の全体像

この問題は、Trustindexの「Instagram Feed」ウィジェットを設置したWordPressサイトで発生する。プラグインは管理画面のトラブルシューティング用に /wp-json/trustindex_feed_hook_instagram/troubleshooting というRESTエンドポイントを用意している。このエンドポイントに正しい署名付きリクエストを送ると、プラグインが保存している全オプション、つまりInstagramのアクセストークンや各種設定をJSON形式で返してしまう。
認証にはHMAC-SHA256による署名検証が使われているが、その署名用の秘密鍵(キー)がサイトごとに公開されている「パブリックID」になっている。このIDは、プラグインが生成するCDNのURL(https://cdn.trustindex.io/wp-feeds/XX/パブリックID/data.json)に含まれ、ページのソースコードやネットワークリクエストを覗けば誰でも取得できる。つまり署名の計算に必要な材料がすべて攻撃者の手に渡ってしまうため、認証がまったく機能していない状態だ。
影響は深刻だ。漏洩したInstagramアクセストークンを使えば、サイト運営者になりすましてInstagram Graph APIを呼び出し、プロフィール情報の取得やメディア投稿の操作が可能になる。トークンの有効期限が切れるか運営者が手動で失効させるまで、不正利用のリスクが続く。
自分のサイトが影響を受けるかどうかの確認方法

まず、TrustindexプラグインをインストールしてInstagramフィードを表示しているサイトが対象だ。それ以外のフィード(FacebookやGoogleレビューなど)を使っているだけの場合は、今回のエンドポイントとは関係がない。確認手順は次の3ステップで行える。
STEP 3の詳細は、UNIXのターミナルで以下のようなリクエストを投げる。HMACの計算にはパブリックIDと現在のUNIXタイムスタンプを使うため、スクリプトを組むか手動で計算する必要がある。
# PUBLIC_ID と TIMESTAMP は各自の値に置き換える
PUBLIC_ID="取得したパブリックID"
TIMESTAMP=$(date +%s)
SIGNATURE=$(echo -n "$TIMESTAMP" | openssl dgst -sha256 -hmac "$PUBLIC_ID" | awk '{print $2}')
curl -H "X-Signature: $SIGNATURE" -H "X-Timestamp: $TIMESTAMP" \
"https://あなたのサイトドメイン/wp-json/trustindex_feed_hook_instagram/troubleshooting"レスポンスに source.access_token や access_token といった文字列が含まれていれば、情報が丸見えの状態だと判断できる。この確認はあくまで自己診断用であり、他者のサイトに対して行ってはならない。
修正パッチが配布されるまでに取るべき応急措置

プラグイン開発者から公式のアップデートが提供されるまでは、以下のいずれかの方法で該当エンドポイントへの外部アクセスを完全に遮断する。
.htaccessでエンドポイントをブロックする
サーバーがApacheを使っている場合、WordPressのインストールディレクトリにある.htaccessファイルに以下の記述を追加する。これにより、該当URLへのリクエストは403 Forbiddenで弾かれる。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^wp-json/trustindex_feed_hook_instagram/troubleshooting - [F]
</IfModule>functions.phpでREST APIアクセスを制限する
テーマのfunctions.php(子テーマ推奨)に下記のコードを追加すると、未ログインユーザーからの該当エンドポイントへのアクセスを拒否できる。管理画面にログインしているユーザーは引き続き利用できるため、サポートが必要になった際にも支障がない。
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
$current_route = $GLOBALS['wp']->query_vars['rest_route'] ?? '';
if ( strpos( $current_route, '/trustindex_feed_hook_instagram/troubleshooting' ) !== false && ! is_user_logged_in() ) {
return new WP_Error(
'rest_forbidden',
'このエンドポイントへのアクセスにはログインが必要です。',
array( 'status' => 403 )
);
}
return $result;
} );プラグインを一時停止する判断
Instagramフィードの表示が必須でないなら、脆弱性が修正されるまでプラグイン自体を無効化するのが最も確実だ。フィードが表示されなくなる影響が許容できるビジネスであれば、この選択肢も検討しよう。
すでにトークンが漏洩した可能性がある場合の対処

アクセスログを精査して不審なリクエストがなかったか確認するのが先決だが、ログが十分に残っていないケースも多い。疑わしい場合は、以下の手順でトークンを強制的に無効化し、新しいトークンを再発行する。
特にInstagram Graph APIのアクセストークンは長期トークン(Long-Lived Token)で運用していることが多く、一度漏洩すると数カ月単位で悪用されるリスクがある。トークン失効後は、フィードが一時的に表示されなくなるが、再設定すればすぐに復旧する。
根本的な原因と再発防止の考え方

今回の脆弱性の本質は、認証用の秘密情報が公開前提の値になっている設計ミスにある。HMAC署名を使うこと自体は正しいが、秘密鍵が「誰でも見られるURLの一部」にある時点でセキュリティは成り立たない。
プラグイン開発者側が取るべき修正は、プラグイン有効化時にランダムなシークレットを wp_options テーブルに保存し、その値を署名キーに使う方式へ変更することだ。さらに、トラブルシューティングという目的を考えれば、current_user_can('manage_options') で管理者権限を要求するだけでも十分な防御になる。このエンドポイントはあくまでサポートスタッフ向けであり、未認証ユーザーに開放する理由は一切ない。
サイト運営者としても、すべてのプラグインを無条件に信頼するのではなく、導入後に「どんなRESTエンドポイントが増えたか」「公開される情報はないか」をセキュリティプラグインや手動チェックで確認する習慣が身を守る。WordPressのサイトヘルス機能やQuery Monitorのようなツールを普段から使い、異常なAPIリクエストがないか注視しておくことが再発防止につながる。
よくある質問
プラグインのどのバージョンから修正されますか
2026年6月17日時点では、開発者は調査中と回答しており修正バージョンは未発表だ。Trustindexの公式チェンジログとWordPress管理画面の更新通知を定期的に確認し、セキュリティアップデートが配信され次第ただちに適用する必要がある。
応急処置としてプラグインを無効化すると、フィードはどうなりますか
プラグインを無効化すると、Instagramフィードは表示されなくなる。ただ、表示崩れが起こるだけでサイト全体がダウンするわけではない。トークン漏洩のリスクと天秤にかけて、ビジネス上の重要性が高い場合は上記の.htaccessやfunctions.phpによる遮断を選ぶほうが現実的だ。
Instagramのトークンを変えたあと、再度漏洩することはありますか
アプリやサーバー側の脆弱性が修正されていない限り、新しいトークンも同じエンドポイントから再び漏洩する可能性がある。必ず、アクセス制限の応急措置を先に施したうえでトークンを再発行する順序を守ってほしい。
FacebookやGoogleのフィードにも同じ問題はありますか
今回確認されたのは trustindex_feed_hook_instagram のエンドポイントのみだが、同じ認証設計を他のフィード用エンドポイントにも流用している可能性は否定できない。不安があれば、trustindex_feed_hook_facebook や trustindex_feed_hook_google といった類似のエンドポイントが存在しないか、REST APIのルート一覧で確認しておくと安心できる。
自分のサイトがすでに攻撃されたかどうか確かめる方法はありますか
サーバーのアクセスログに /wp-json/trustindex_feed_hook_instagram/troubleshooting へのリクエストが記録されていれば、それが正規のサポート用途か攻撃かを判別する必要がある。あわせて、Instagram Graph APIの使用状況をFacebook開発者コンソールの「アプリのインサイト」で確認し、見覚えのないAPIコールや異常なリクエスト数がないかを調査するのが確実だ。
この記事のポイント
- Trustindexプラグインのトラブルシューティング用RESTエンドポイントが認証不備によりInstagramアクセストークンを露出させている
- 原因はHMAC署名の秘密鍵として、誰でも取得できるパブリックIDを使用している設計ミス
- 修正パッチが配布されるまでは、.htaccessかfunctions.phpでエンドポイントへの外部アクセスを遮断する
- トークン漏洩が疑われる場合はInstagram側でトークンを即時失効させ再発行する
- 常にプラグインのREST APIエンドポイントを定期的に監視し、不要な露出がないか確認する習慣が再発防止の鍵

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

OptinMonsterなど4プラグインのサプライチェーン攻撃、不正管理者を確認する手順
OptinMonster、TrustPulse、PushEngage、Uncanny Automator のいずれかのプラグインを導入している場合、ただちに管理画面の全ユーザー一覧を確認し、身に覚えのない管理者アカウントが作成されていないか点検する必要がある。これらのプラグインに使用されている CDN スクリプトが改ざんされ、悪意ある管理者を自動生成するサプライチェーン攻撃が 2026 年 6 月に確認された。
何が起きたのか 今回のサプライチェーン攻撃の仕組み

攻撃者はプラグインのソースコードそのものを改変したわけではなく、各プラグインが配信に利用している外部 CDN 上のスクリプトファイルに細工を施した。このため、プラグイン自体のバージョンアップや通常のマルウェアスキャンでは異常を検知しにくいのが特徴だ。
改ざんされたスクリプトは、サイトのフロントエンドに読み込まれる形で実行され、裏側で WordPress のユーザー登録 API を突いて新規の管理者アカウントを作成する。攻撃者がすでに管理者権限を取得している場合、サイトの改ざんや情報の窃取が自由に行える極めて危険な状態となる。
国内の WordPress サイトでも、マーケティングツールとして該当プラグインを導入しているケースは少なくない。攻撃が表面化した時点で、該当プラグインの開発元はすでに CDN 側の改ざんを修正し、侵害された可能性のある顧客への通知を進めているが、すべてのサイト運営者が自らチェックを行うことが被害の深刻化を防ぐうえで決定的に重要だ。
サイトに悪意ある管理者は存在しない。
サイト訪問時に不正スクリプトが実行され、未知の管理者アカウントが自動生成される。
自分は対象か 影響を受けるプラグインを導入していないか確認する

今回のサプライチェーン攻撃の対象として報告されたのは次の 4 製品だ。いずれか 1 つでも導入している場合は、影響を受けた可能性を前提に全手順を実行する必要がある。
- OptinMonster(オプティンモンスター)
- TrustPulse(トラストパルス)
- PushEngage(プッシュエンゲージ)
- Uncanny Automator(アンキャニーオートメーター)
プラグイン一覧ページでこれらの名称を検索すれば、導入の有無はすぐに判別できる。ただし、テーマの functions.php に直接コードを埋め込んでいる場合や、カスタム実装で CDN スクリプトを読み込んでいる場合はプラグイン管理画面では発見できないため、サイトのソースコードやタグマネージャーの設定も併せて確認するとより確実だ。
不正な管理者アカウントを特定して削除する手順

まず管理画面の「ユーザー」→「ユーザー一覧」を開き、管理者権限を持つアカウントをすべて確認する。身に覚えのない管理者アカウントが存在する場合は、そのアカウントが攻撃によって作成された可能性が極めて高い。
削除時に「投稿の所有権」をどうするか
不正な管理者を削除する際、WordPress はそのユーザーが作成した投稿の帰属先を尋ねてくる。該当ユーザーが攻撃者である場合、そのアカウントが作成した投稿そのものも悪意あるコンテンツであることが多いため、すべて「削除」を選択して問題ない。もし誤って残す必要がある場合のみ、正当な管理者に帰属を変更する。
不正な管理者アカウントがゼロでも油断できない理由
攻撃スクリプトは任意のタイミングで管理者を作成する仕組みになっている。現在のユーザー一覧に不審点がなくても、改ざんされた CDN スクリプトが過去に読み込まれたことがあれば、攻撃者がすでにアクセストークンや認証情報を窃取している可能性を排除できない。必ず後述の予防措置まで実行する必要がある。
感染後のサイトを安全な状態に戻すために今すぐやるべきこと

該当プラグインを完全に削除して再インストールする
単なる無効化では不十分だ。該当プラグインを一度完全に削除し、公式リポジトリまたは開発元から最新版をダウンロードして再インストールする。これにより、仮に攻撃者がプラグインの管理画面内に保存していた設定値や隠しコードを仕込んでいたとしても、完全に除去できる。
全ユーザーのパスワードをリセットし多要素認証を有効にする
攻撃者がすでに正当なユーザーのログイン情報を盗んでいる可能性を想定し、サイトの全ユーザー(特に管理者・編集者権限)のパスワードを変更する。加えて多要素認証(二段階認証)をただちに有効にし、パスワード単体ではログインできない設定に切り替えることが再侵入の防止に直結する。
WP ソルトキーを強制的に無効化する
wp-config.php に定義されている認証用のソルトキー(AUTH_KEY、SECURE_AUTH_KEY、LOGGED_IN_KEY、NONCE_KEY とそれぞれの SALT)をすべて新しい値に置き換える。これで既存のすべてのログインセッションが即座に無効になり、攻撃者が盗んだクッキーではアクセスできなくなる。WordPress の公式ソルト生成ツールを使えば、ランダムな値がすぐに発行できる。
.htaccess や wp-config.php に仕込まれたバックドアを点検する
管理者権限を取得した攻撃者は、テーマファイルやプラグインファイルを編集してバックドアを仕込むことが多い。特に functions.php や wp-config.php、.htaccess に不自然なコードが追記されていないかを FTP またはサーバー管理画面のファイルマネージャーで直接確認する。見慣れない base64 デコード処理や eval 関数を含むコード、不明な外部 URL へのリクエストがあれば攻撃の痕跡だ。
なぜ通常のウイルススキャンでは検知されなかったのか

一般的なセキュリティプラグインは、サーバー上の PHP ファイルやデータベースの不審なパターンをスキャンする。しかし今回の攻撃は、問題のあるコードがサイト外部の CDN 上にあり、ブラウザの JavaScript 実行を通じて攻撃が成立する仕組みだった。サーバー側のファイルに痕跡が残らないため、従来型のマルウェアスキャンでは検出が困難だった。
この手口が示しているのは、外部リソースに依存するプラグインは、その配信網が侵害された場合にプラグイン本体の安全性とは無関係に危険になりうるという現実だ。CDN から読み込まれるスクリプトに対しては、Subresource Integrity(SRI)属性による改ざん検知が有効だが、これを実装しているプラグインは現状ほとんど存在しないことも今回の問題を深刻にした。
再発を防ぐために導入すべき具体的な対策
外部 CDN スクリプトを監視する仕組みを整える
すべての外部スクリプトをやみくもに拒否するのは現実的ではないが、コンテンツセキュリティポリシー(CSP)ヘッダーを適切に設定することで、どの CDN からのスクリプト実行を許可するかを明示的に制御できる。許可リストにないドメインからのスクリプトはブラウザ側でブロックされるため、未知の改ざんが発生した場合の被害を抑える障壁になる。
管理者ユーザーの監査ログを定期的に確認する
新しい管理者の追加や権限変更を記録する監査ログプラグインを導入しておけば、今回のように見知らぬアカウントが作成されたときに即座に気づける。攻撃が CDN 経由で行われたとしても、サーバー側でユーザーが作成される瞬間をログに残すことができるため、異常検知の有効な補助線になる。
利用プラグインの外部依存関係を定期的に見直す
導入済みのすべてのプラグインが、どの外部ドメインに対してリクエストを送っているかを定期的に棚卸しする習慣をつけると、今回のようなサプライチェーンリスクの芽を早期に見つけやすくなる。プラグインがバックグラウンドで読み込んでいる CDN スクリプトや API エンドポイントを把握していれば、問題発生時に影響範囲を素早く特定できる。
よくある質問
該当プラグインを無効にしただけで安全といえるか
安全とはいえない。改ざんされたスクリプトが過去に読み込まれた時点ですでに不正な管理者が作成されている可能性がある。無効化では既存の被害は解消されず、削除と再インストール、およびユーザー一覧の精査が必須になる。
不正な管理者が見つからなかった場合でも何かすべきことはあるか
全ユーザーのパスワードリセットとソルトキーの変更は必ず実行する。改ざんスクリプトが認証クッキーやアクセストークンを窃取していた場合、攻撃者は管理者アカウントを作らずとも正当なユーザーとしてログインできる可能性があるためだ。
これらのプラグインは今後も使い続けても大丈夫か
各開発元はすでに CDN の改ざんを修正し、再発防止策を強化している。しかしどのプラグインでも外部依存がある以上、同様のリスクをゼロにすることは不可能だ。使用を継続する場合は、この記事で述べた監視と予防の仕組みを併せて導入することが前提になる。
WordPress 本体や他の無関係なプラグインまで影響を受けるのか
今回の攻撃は対象プラグインの CDN スクリプト経由でのみ実行された。ただし管理者権限を奪取された後は、WordPress 本体や他のプラグインを含め、サイト全体が改ざん対象になりうる。該当プラグインを使用していた場合は、サイト全体のファイル整合性チェックを併せて行うとよい。
この記事のポイント
- OptinMonster、TrustPulse、PushEngage、Uncanny Automator 利用者は要緊急対応
- 不正な管理者アカウントの有無を「ユーザー一覧」で即座に確認する
- 該当プラグインの完全削除と再インストールで痕跡を除去する
- 全ユーザーパスワードのリセットとソルトキー変更が防御の基本線
- CSP 設定と管理者監査ログで将来の類似攻撃に備える

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

JavaScriptがログアウト時に動かない原因と直し方
管理画面にログインしているときだけ JavaScript が動き、ログアウトすると止まる。この現象の原因は、ほぼ「スクリプトの読み込み順序」と「キャッシュ・最適化プラグインの挙動」のどちらか、あるいは両方の組み合わせだ。ログイン時は管理バー用のスクリプト等が読み込まれるため依存関係が偶然成立し、ログアウト時にそれが外れてエラーになるケースが多い。
ログアウト時だけ JavaScript が動かなくなる仕組み

このデモは典型的な依存関係の崩れを示している。ログイン中は WordPress が管理バーやフッターに jQuery を読み込むため、その後に記述されたスクリプトが偶然動く。ログアウトすると jQuery が存在せず、$ is not defined や jQuery is not defined といったエラーで止まる。
HTML ブロックに直接書いた JavaScript が招く問題

WordPress の「カスタム HTML」ブロックに <script> タグを直書きする方法は、一見手軽だが制御が難しい。出力される位置がテーマやブロック配置に依存し、jQuery などのライブラリより前に実行されれば必ず失敗する。さらにインラインスクリプトは多くのキャッシュプラグインで最適化対象から外されたり、結合・遅延読み込みの対象にならず、ログアウト時だけ二重に不利な状況を生む。
HTML ブロック直書きスクリプトの3つの弱点
- 読み込み順序を制御できない(テーマの render 順に依存する)
- jQuery の依存関係を WordPress に伝えられない
- キャッシュ・圧縮プラグインがスクリプトとして認識しない場合がある
ログアウト時でも動くようにする正しい組み込み手順

原則は「JavaScript は HTML ブロックに直書きせず、WordPress の仕組み(wp_enqueue_script)で読み込む」ことだ。すでに直書きで動いているものを移行するには、以下の手順で進める。
STEP 1 既存の script タグを外部ファイルに移す
HTML ブロック内の <script>〜</script> 部分だけを抜き出し、子テーマのフォルダ内に testimonial-slider.js のような名前で保存する。<script> タグそのものは不要で、中身のコードだけを移す。HTML ブロックにはスライダーの構造(ul や div のマークアップ)だけを残す。
STEP 2 functions.php で安全に読み込む
子テーマの functions.php に以下のコードを追加する。管理画面ではなくフロントエンドだけに読み込ませるために wp_enqueue_scripts フックを使う。依存関係として jquery を指定すれば、WordPress 本体の jQuery が先に読み込まれてから実行される。
function my_testimonial_slider_script() {
wp_enqueue_script(
'testimonial-slider',
get_stylesheet_directory_uri() . '/testimonial-slider.js',
array('jquery'),
'1.0.0',
true
);
}
add_action('wp_enqueue_scripts', 'my_testimonial_slider_script');最後の引数 true はフッターで読み込む指定だ。スライダーの DOM 要素が本文中に存在する場合はフッター読み込みで問題ない。もしスライダーを本文より前に実行する必要があるなら false にしてヘッダーで読ませるが、多くのケースではフッターで十分だ。
STEP 3 $ の衝突を防ぐ
WordPress の jQuery は noConflict モードで動作しているため、$ がそのまま使えない環境がある。古いコードを流用している場合は $ is not a function エラーが起きやすい。回避策として、外部ファイル全体を即時実行関数で囲み、引数で $ を受け取る記法が安全だ。
(function($) {
$(document).ready(function() {
// ここにスライダーのコード
});
})(jQuery);STEP 4 キャッシュプラグインでスクリプトを除外する
ここまで対応しても直らない場合、キャッシュや最適化プラグインが原因の可能性が高い。ログアウト時はページキャッシュが有効になり、スクリプトの遅延読み込みや結合が適用される。自前の testimonial-slider.js をこれらの処理から除外する必要がある。
プラグインの設定画面で「スクリプトの除外」「遅延読み込みの除外」といった項目を探し、testimonial-slider(ハンドル名)または testimonial-slider.js(ファイル名の一部)を指定する。除外後は必ずキャッシュを全削除してからログアウト状態で確認する。
Elementor のフックやテーマのアクションフックを使った場合の注意点

テーマ付属のフック(GeneratePress の Element など)に HTML ブロックごと差し込む方法も考えられるが、根本的にはスクリプトの読み込み順序問題は同じだ。フックで出力する位置を変えても、jQuery より前に呼ばれるリスクは残る。フックを使う場合でも、スクリプト部分は wp_enqueue_script に任せ、フックにはマークアップだけを出力する形が堅実だ。
Elementor Pro の「カスタムコード」機能を使っているなら、その中に script タグを書くのではなく、同様に子テーマのファイルとして切り出してハンドル登録するほうが制御できる。どうしても直書きが必要なら、カスタムコードの「場所」設定を「本文の終了タグ直前」にし、さらにコード内で jQuery を明示的に使う($ を使わない)ことでエラーを減らせる。
よくある質問
コンソールに「$ is not defined」と出るがどう直せばいいか
jQuery が読み込まれる前に $ を使っているか、noConflict モードで $ が無効になっている。即時関数で (function($) { ... })(jQuery); とラップし、すべての $ をこのスコープ内に収めれば解決する。
functions.php を編集せずに直す方法はあるか
「WPCode」などのコードスニペット管理プラグインを使えば、管理画面から wp_enqueue_script のコードを登録できる。functions.php を直接触りたくない場合の現実的な代替手段だ。スニペットの実行場所を「フロントエンドのみ」に設定するのを忘れないようにする。
キャッシュを削除しても直らないのはなぜか
ブラウザキャッシュだけを消していて、サーバー側のページキャッシュや CDN キャッシュが残っているケースが多い。WordPress のキャッシュプラグインの「すべてのキャッシュを削除」を実行し、さらに CDN を使っている場合はその管理画面からもパージする。シークレットウィンドウで確認するとブラウザキャッシュの影響を除外できる。
スライダーのマークアップだけ残して script を外したら表示が消えた
新しく作った JS ファイルが正しく読み込まれていない。ブラウザの開発者ツールの「ネットワーク」タブで testimonial-slider.js が 200 番で返っているか確認する。404 ならパスが間違っている。読み込まれているのに動かない場合は、コンソールに別のエラーが出ていないか調べる。
この記事のポイント
- ログアウト時だけ JavaScript が動かない原因は、jQuery の依存切れとキャッシュ最適化の複合
- HTML ブロックへの script 直書きは読み込み順序を制御できず、根本対策にならない
- wp_enqueue_script で jQuery 依存を明示し、外部ファイルとして切り出すのが正攻法
- 即時関数で $ の衝突を防ぎ、キャッシュプラグインでは独自スクリプトを除外対象に追加する
- Elementor やテーマフックを使う場合も、スクリプトだけは enqueue に任せる設計が堅実

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

特定商品ブロックを設置した固定ページでfatal errorが発生する問題の直し方
特定商品ブロックを固定ページに配置したときに「Uncaught Error Call to a member function get_id() on null」というfatal errorが表示されるのは、PreCart for WooCommerce のバグが原因だ。プラグインを最新バージョンへ更新するか、functions.php へ一時的な修正コードを追加すれば直る。
なぜ固定ページ上の商品ブロックで fatal error が起こるのか

PreCart は WooCommerce の商品情報を扱うフィルターフック(woocommerce_product_add_to_cart_text など)にコールバック関数を登録し、その中で global $product から商品オブジェクトを取得して $product->get_id() を呼び出している。しかし、ブロックエディタで「特定商品」ブロックを通常の固定ページに配置すると、WooCommerce のブロック表示パイプラインではグローバル変数 $product が null のままフィルターが走るケースがある。PreCart のコードには null チェックがないため、null に対して get_id() を呼び出してしまい、致命的なエラーでページ全体が落ちる。
$product が null のままコールバックが実行される$product->get_id() で致命的エラー発生(画面が真っ白になる)影響を受けるメソッドは change_add_to_cart_text()、display_pre_order_messgae()、display_pre_order_badge() など、いずれも保護コードがない。WooCommerce の商品ブロックを店舗ページ以外で使っているサイトはすべてこの問題に遭遇し得る。
PreCart を更新してエラーを解消する手順

開発元はこの問題を認識しており、すでに修正アップデートがリリースされている。まずは管理画面からプラグインを最新版に上げるのが最も安全で確実な対処法だ。
更新通知が表示されない場合
「ダッシュボード」→「更新」から更新の再確認を行うか、PreCart のプラグインページで一度「プラグインを削除」→ 公式リポジトリから再インストールする方法もある。ただしこの場合、設定がリセットされる可能性があるため、事前に PreCart の設定をメモしておくかエクスポート機能があれば使っておくと安心だ。
functions.php で null チェックを追加して一時的に対処する方法

どうしてもすぐにプラグインを更新できない場合や、何らかの理由で更新後に問題が残る場合は、テーマの functions.php にフックを追加して一時的にエラーを回避できる。
/**
* PreCart の null チェック不足による fatal error を回避(一時的対応)
*/
add_filter( 'woocommerce_product_add_to_cart_text', function( $text, $product ) {
if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
return $text;
}
// 以下は原本の処理が走るが、早期リターンで保護
return $text;
}, 1, 2 );
add_filter( 'woocommerce_single_product_summary', function() {
global $product;
if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
return;
}
// 同様に早期リターン
}, 1 );上記のコードは PreCart が使っているのと同じフックに、より優先度の高いコールバック(優先度 1)で null チェックを追加し、商品オブジェクトが存在しないときは処理を打ち切る仕組みだ。PreCart のフィルターよりも先に実行されるため、致命的エラーに至る前に関数を抜けられる。
$product->get_id();
$product->get_id();
functions.php 編集時の注意点
子テーマを使っていない場合、テーマ更新で修正が上書きされるリスクがある。必ず子テーマの functions.php にコードを追加するか、Code Snippets プラグインでコードを管理するのが望ましい。また、この一時対応はあくまで応急処置であり、PreCart の他の機能が正常に動作しない可能性もゼロではない。早めに公式アップデートを適用して、追加コードは削除する。
手動修正後に確認しておきたいポイント

- 一時的なコードを追加した後、サイトの表示速度やエラーログに変化がないか定期的にチェックする
- PreCart の機能(カート追加テキストの変更や予約注文バッジなど)が期待どおり動作しているかテストする
- PHP のエラーログを確認し、別の箇所で同様の null 参照エラーが隠れていないか調べる
- サイト全体のキャッシュをクリアし、CDN を利用している場合は CDN キャッシュも破棄する
- PreCart の更新が確認できたら必ずプラグインを最新版に上げ、追加コードを削除する
よくある質問
PreCart 以外のプラグインでも同じように商品ブロックでエラーが出ることはありますか
ある。WooCommerce のブロックを通常ページで使うと、$product グローバルを正しく取り扱っていない他の拡張プラグインでも同様の null 参照エラーが起きるケースが報告されている。エラーの文面に別のプラグイン名が含まれている場合は、そちらの開発元へ報告しつつ、同じように functions.php で早期リターンを追加すれば応急回避できることが多い。
WooCommerce の商品ブロックを固定ページで使うこと自体は問題ないのでしょうか
WooCommerce のブロックは基本的に店舗ページや商品ページで使うことを想定しているが、WordPress の標準ブロックとして技術的にはどの投稿タイプでも利用できる。プラグインがグローバル変数の有無を適切にハンドリングしていれば固定ページで使っても問題は起きない。ただ、テーマやプラグインが認めるまで、動作確認は入念に行ったほうがよい。
エラーメッセージが表示されずに画面が真っ白になる場合はどうすればよいですか
WordPress が致命的エラーを表示しない設定(WP_DEBUG が false)のときは、管理画面のメールに送られる復旧モード用のリンクを探すか、サーバーの PHP エラーログを確認する。wp-config.php で define('WP_DEBUG', true); を一時的に有効にすれば、画面上にエラー詳細が表示され、原因を特定しやすくなる。なお、本番環境ではデバッグモードをすぐに無効に戻すこと。
管理画面にも入れなくなってしまった場合はどうすれば直りますか
FTP またはレンタルサーバーのファイルマネージャーで /wp-content/plugins/precart/ ディレクトリの名前を一時的に変更(例:precart_deactivated)すれば、プラグインが無効化されて管理画面に再ログインできる。その後、前述の更新や一時コードで対処し、ディレクトリ名を元に戻す。
この記事のポイント
- 固定ページに WooCommerce 商品ブロックを配置したときの fatal error は PreCart の null チェック不足が原因
- 解決策は PreCart プラグインの最新版への更新が最も安全で確実
- すぐに更新できない場合は、functions.php にフックで早期リターンを追加すれば応急回避できる
- functions.php 編集は子テーマで行い、アップデート後は必ず追加コードを削除する
- 管理画面に入れなくなったら FTP でプラグインフォルダ名を変更し無効化する

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

AI EngineとJetpackが衝突してGeminiが使えない時の解決策
AI Engine プラグインをバージョン 3.5.5 以降にアップデートすれば、この問題は即座に解決する。根本原因は Jetpack が REST API に追加する整数型 enum フィールドを、Google Gemini がツール定義で拒否していたことにある。AI Engine の開発者がこのスキーマ生成ロジックを修正し、文字列型以外の enum を自動除去するようになった。
どのようなエラーが発生するのか

Desktop Commander で AI Engine を MCP サーバーとして管理モードで接続し、AI モデルに Google Gemini を指定すると、次のようなエラーで通信が失敗する。
「GenerateContentRequest.tools[0].function_declarations[30].parameters.properties[jetpack_publicize_connections].items.properties[status].enum: only allowed for STRING type」という趣旨のエラーが返る。翻訳すると「enum は STRING 型にしか使えない」という厳格な制約に違反した形だ。
管理画面では具体的に「AI Engine が Gemini API からの応答に失敗しました」といった形で表示され、チャットが開始できないか、途中で止まる。管理モードでなければ発生しないエラーだ。
なぜ Jetpack と AI Engine が衝突するのか

核心は Google Gemini API の「ツール定義」に対する極めて厳格なバリデーションにある。Gemini は利用可能な関数のパラメータをスキーマで受け取るが、enum(許容値の固定リスト)を使う場合、そのデータ型を必ず文字列にしなければならない。
一方 Jetpack は、WordPress の投稿作成や更新時に使われる REST API エンドポイントへ、ソーシャルメディア連携用のフィールドを動的に追加している。その中の jetpack_publicize_connections フィールドには status というパラメータがあり、Jetpack はこれを整数型の enum([0, 1])として定義している。
AI Engine が WordPress のスキーマ全体を走査して Gemini 向けのツールリストを組み立てる際、この整数型 enum をそのまま継承してしまう。その結果、Gemini API がリクエスト全体を「400 Bad Request」ではねつける流れだ。
読み取り専用モードならば投稿作成系のツールが含まれないため、このエラーは発生しない。管理モードで書き込み権限を付与する場合に限って表面化する。
AI Engine 3.5.5 以降へのアップデートで恒久修正する

AI Engine の開発者によって、バージョン 3.5.5 で根本的な修正が加えられた。ツールスキーマを作成する際、文字列型以外の enum 定義を自動的に除去する処理が追加されている。
スキーマキャッシュのバージョンも同時に引き上げられているため、更新後に手動でキャッシュをクリアする必要はない。自動的に再生成され、Jetpack の整数型 enum は除去された状態でツールリストが構築される。
どうしてもアップデートできない場合の手動修正
何らかの理由で AI Engine を最新版にできない場合、子テーマの functions.php または Code Snippets プラグインに以下のコードを追加し、Jetpack の整数型 enum フィールドを強制的に文字列型へ変換できる。
<?php
/**
* Jetpack と AI Engine、Google Gemini の競合を修正する。
* Jetpack の status enum フィールドを文字列型に変換する。
*/
add_action( 'wp_enqueue_scripts', 'enqueue_parent_styles' );
function enqueue_parent_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
add_action( 'rest_api_init', 'fix_jetpack_enum_for_gemini', 9999 );
function fix_jetpack_enum_for_gemini() {
global $wp_rest_additional_fields;
if ( ! empty( $wp_rest_additional_fields ) ) {
foreach ( $wp_rest_additional_fields as $post_type => $fields ) {
if ( isset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections'] ) ) {
if ( isset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status'] ) ) {
// 問題を起こす整数 enum を除去
unset( $wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status']['enum'] );
// データ型を文字列に明示
$wp_rest_additional_fields[$post_type]['jetpack_publicize_connections']['schema']['items']['properties']['status']['type'] = 'string';
}
}
}
}
}
?>コード追加だけでは修正されないケースがある。AI Engine はツールリストをデータベースに強力にキャッシュしているため、キャッシュを強制的に再生成させる必要がある。
Jetpack を無効化した状態でチャットを実行することで、AI Engine は Jetpack 関連フィールドのないスキーマを新規に作成する。Jetpack を再有効化した後は上記のフィルタが働き、問題の enum がスキーマに混入することはなくなる。
よくある質問
Jetpack を使っていなければこの問題は起こらないのか
Jetpack の jetpack_publicize_connections フィールドが原因であるため、Jetpack を導入していなければ発生しない。ただし、他のプラグインも整数型 enum を REST API に追加している場合は似たエラーが出る可能性がある。その場合も AI Engine 3.5.5 以降であれば同様に自動除去される。
読み取り専用モードではなぜ問題ないのか
読み取り専用モードでは、投稿の作成や更新といった書き込み系のツールが Gemini に送信されない。問題の jetpack_publicize_connections フィールドは投稿作成時に登場するため、ツールリストから除外される。管理モードだけが影響を受ける。
AI モデルが Gemini 以外でも同じエラーは出るか
このエラーは Gemini のツール定義バリデーションが特に厳格なために発生する。OpenAI の GPT シリーズなど、他の AI モデルでは整数型 enum を許容するものもあるが、根本原因はスキーマにあるため、どのモデルでも潜在的な問題になりうる。AI Engine 3.5.5 の修正で全モデルに対応できる。
AI Engine 3.5.5 にアップデートした後、スキーマキャッシュは本当に自動クリアされるのか
開発者によれば、スキーマキャッシュのバージョンナンバーが引き上げられているため、更新後の初回リクエスト時に自動的に再生成される。手動でキャッシュを削除する操作は不要。もし不安があれば、AI Engine の設定画面からキャッシュを手動クリアしても問題ない。
この記事のポイント
- AI Engine 3.5.5 以降のアップデートで根本解決する
- 原因は Jetpack の整数型 enum を Gemini が拒否するため
- 読み取り専用モードでは書き込み系ツールが送信されず問題は出ない
- 手動修正する場合は Jetpack 一時無効化によるキャッシュ再生成が必須
- 修正後は文字列型以外の enum が自動除去され、あらゆる AI モデルで安定する

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

PHP 8.4にしたらmodern-events-calendar-liteで翻訳読み込みエラーが出た時の対処法
PHP 8.4への移行直後にデバッグログへ記録された「_load_textdomain_just_in_time」の通知は、PHPのバージョンが原因ではない。WordPress 6.7で追加された新しい翻訳読み込み機構が、modern-events-calendar-liteプラグインの不適切な翻訳呼び出しを検出し、注意喚起しているだけだ。サイトの動作には影響しないが、デバッグモードを有効にしているとログを埋め尽くす。根本的な解決はプラグインのバージョンアップだが、更新が提供されていなければ数行のコードで通知を抑制できる。
なぜPHP 8.4への切り替え後にこの通知が現れたのか

実際のところ、PHP 8.4と翻訳読み込みの仕組みには直接の関係はない。今回の通知が突然ログに現れたのは、ふたつのタイミングが重なったためだ。ひとつは WordPress 6.7 で導入された「just-in-time翻訳読み込み」機能が、従来よりも厳密にプラグインのコードをチェックするようになったこと。もうひとつは、PHPのバージョンを上げるタイミングでデバッグモード(WP_DEBUG)を有効にした、もしくはデバッグログの出力先を確認したことだ。
つまり、PHP 7.4 の環境でも WordPress 6.7 以降であれば同じ通知は発生していた可能性が高い。PHP 8.4 にしたからといって、追加のエラーが生じたわけではないと捉える必要がある。デバッグログを初めて見たことで、以前から存在していた通知に気づいたという構図になる。
_load_textdomain_just_in_time通知の正体

WordPress 6.7 では、翻訳ファイルの読み込みをできるだけ遅延させる「just-in-time翻訳」の仕組みが強化された。その中核を担うのが _load_textdomain_just_in_time という内部関数だ。この関数は、プラグインやテーマが本来「init」アクション以降に行うべき翻訳ファイルの読み込み(textdomainのロード)を、それより早い段階で実行しようとした場合に検知し、開発者向けの通知を発生させる。
表示されるエラーメッセージの日本語訳は「_load_textdomain_just_in_time 関数が正しく呼び出されませんでした。modern-events-calendar-lite ドメインの翻訳の読み込みが早すぎるタイミングで開始されました。」といった趣旨になる。これは「重大なエラー」ではなく「注意(Notice)」であるため、サイトの表示が崩れたり、機能が停止したりすることはない。
PHP Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the modern-events-calendar-lite domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later.
-- デバッグログから当該通知がなくなり、本来のエラーだけが記録される --
上記のBefore/Afterのように、この通知を抑制すればデバッグログがすっきりし、本当に注意すべきエラーを見落としにくくなる。通知の表示自体はWordPress側の仕様変更によるものなので、PHP 8.4にしたからといって新たな不具合が混入したわけではないと理解しておこう。
翻訳読み込み通知を解消する手順

プラグインの更新状況を確認する
まずは、modern-events-calendar-liteプラグインが最新版になっているか管理画面の「プラグイン」一覧から確認する。WordPress 6.7への対応が完了していれば、アップデートを適用するだけで通知は自然に消える。ただし、このプラグインはしばらく大きな更新がないケースもあり、執筆時点では修正が提供されていない可能性が高い。
更新が見つからない場合は次の手順に進む。開発元が対応しないあいだは、ユーザー側で通知を抑える方法を取らざるを得ない。
コードを追加して通知を抑制する
更新が提供されていない場合でも、WordPressのフィルターフックを使って、modern-events-calendar-liteに限って「_load_textdomain_just_in_time」の通知を発生させないようにできる。具体的には、以下のコードをMUプラグイン(Must-Use Plugin)として配置する。
<?php
/**
* Plugin Name: Suppress MEC Translation Notice
* Description: modern-events-calendar-lite の翻訳読み込み通知を抑制する
*/
add_filter( 'doing_it_wrong_trigger_error', function( $trigger, $function_name, $message, $version ) {
if ( '_load_textdomain_just_in_time' === $function_name && false !== strpos( $message, 'modern-events-calendar-lite' ) ) {
return false;
}
return $trigger;
}, 10, 4 );このコードは「doing_it_wrong_trigger_error」フィルターを利用し、問題の関数名とメッセージ内に当該プラグインのテキストドメインが含まれている場合のみ、通知のトリガーを無効にする。他のプラグインやコアの重要なお知らせには影響を与えないため、安全に使える。
設置方法は、wp-content/mu-plugins/ ディレクトリに任意の名前のPHPファイル(例: mec-translation-suppress.php)を作成し、上記コードを貼り付けるだけ。mu-plugins フォルダが存在しない場合は手動で作成する。MUプラグインを使うと、テーマの切り替えや通常のプラグイン管理の影響を受けず、恒久的にフィルターが適用される。
デバッグログを確認する
コードを追加したあと、再度サイトを表示したり、管理画面にログインし直したりすると、それ以降のデバッグログ(wp-content/debug.log)に当該通知が記録されなくなる。念のため、一度プラグインを無効化・再有効化するか、任意のページを表示してからログを確認すると確実だ。通知が消えていれば対処は完了。もし引き続き同じ通知が残っている場合は、ファイルの設置場所やコードの記述ミスを確認する。
よくある質問
この通知はサイトを停止させるのか
停止しない。WordPressの「Notice」レベルの出力であり、サイトの表示やプラグインの動作そのものにはまったく影響を与えない。デバッグモードが有効な環境でのみログに出力されるものなので、訪問者が目にすることもない。
PHP 8.4に戻したほうがいいのか
戻す必要はない。通知はPHPのバージョンに依存せず、WordPress 6.7の仕様に起因する。PHP 7.4はすでにセキュリティサポートが終了しているため、PHP 8.4を使い続けるほうが望ましい。今回の通知を理由にPHPのバージョンを下げるのは誤った判断だ。
他のプラグインでも同じ通知が出る可能性はあるか
十分にある。WordPress 6.7以降、翻訳の読み込みを「init」より前に行っている多くの古いプラグインやテーマで同様の通知が発生する。同じ仕組みで対処したい場合は、上記のコード内の「modern-events-calendar-lite」の部分を該当するテキストドメインに置き換えればよい。
通知を消すコードを使うとほかのエラーも隠れてしまうのか
今回紹介したフィルターは、関数名とメッセージ内容の両方で限定しているため、ほかの「doing_it_wrong」通知には影響しない。別のプラグインやWordPressコアが発する重要な警告は、従来どおりデバッグログに記録される。ただし、全体的な検証のために、テスト環境でコードの動作を確認してから本番に適用するのが安心だ。
この記事のポイント
- PHP 8.4への切り替え後に出た翻訳通知は、PHPのバージョンが原因ではない
- WordPress 6.7のjust-in-time翻訳機能が古いプラグインの不備を検出したもの
- サイトの動作には影響せず、デバッグログに記録されるだけのNotice
- プラグインの更新がなければ、フィルターコードで通知だけを抑制できる
- 通知を抑制しても他の重要なエラーは引き続きログに残る

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

WP Rocketのキャッシュ後にモバイルレイアウトが崩れる原因と直し方
WP Rocket のキャッシュ生成後にモバイルレイアウトだけが崩れる場合、Remove Unused CSS(未使用 CSS の削除)や CSS の縮小化(Minify)がレスポンシブ用のメディアクエリや動的クラスを誤って処理している可能性が高い。最初に「未使用 CSS の削除」を無効化するか、モバイル用 CSS を除外設定すれば多くのケースで即座に解決する。
なぜ WP Rocket のキャッシュ後だけモバイル表示が崩れるのか

WP Rocket はサイトの表示速度を上げるため、CSS や JavaScript ファイルを結合・縮小・遅延読み込みする。この最適化処理は強力だが、画面幅に応じてスタイルを切り替えるメディアクエリ(@media)を含むファイルを処理する際に、意図しない形でルールを並べ替えたり削除したりすることがある。
特に問題を起こしやすいのは「未使用 CSS の削除(Remove Unused CSS)」機能だ。この機能はページで実際に使われている CSS だけを抽出して配信する仕組みだが、JavaScript で動的に追加されるクラスや、スクロール位置・タップ操作などユーザーのアクション後に初めて適用されるスタイルを「未使用」と判断して除去してしまう。モバイル表示の崩れは、ほぼこの機能か Critical CSS の生成に起因する。
Cloudflare のキャッシュや Auto Minify が WP Rocket と二重に最適化をかけている場合も、CSS の破損リスクが高まる。キャッシュを両方でクリアしても、最適化処理そのものが走るたびに同じ崩れが再発するのはそのためだ。
■ カラムが重なって文字が読めない
■ ボタンや画像が画面幅をはみ出す
■ WP Rocket の「未使用 CSS 削除」が
@media ルールを除去している■ Critical CSS の再生成と検証
■ Cloudflare 側の二重最適化を停止
■ すべてのデバイスで同一レイアウトを維持
WP Rocket が CSS を処理する流れは、ファイルの読み込み・解析・不要ルールの除去・結合・縮小という順序で進む。このデモは、どの段階でモバイル用のスタイルが失われるかを概念的に示したものだ。
最初に試すべき設定変更と確認手順

未使用 CSS の削除を一時的に無効化する
WordPress 管理画面の「設定」→「WP Rocket」→「ファイル最適化」タブを開き、「CSS ファイル」セクションにある「未使用の CSS を削除(Remove Unused CSS)」のチェックを外す。変更を保存したら、WP Rocket のキャッシュを完全に削除し、Cloudflare を使っている場合は Cloudflare 側のキャッシュもパージする。
シークレットウィンドウまたはキャッシュの残っていない別ブラウザでモバイル表示を確認し、問題が解消したかどうかを判断する。もしこれで直った場合、原因は未使用 CSS の削除処理だと特定できる。
Critical CSS の生成状況を確認する
「未使用 CSS の削除」を有効にしたまま使いたい場合は、Critical CSS(ファーストビュー表示に必要な最小限の CSS)の生成がモバイル用に正しく行われているかを検証する。「WP Rocket」→「ファイル最適化」→「CSS ファイル」セクションにある「クリティカル CSS の最適化(Optimize Critical CSS)」の設定を開き、モバイル向けの Critical CSS が生成されているか確認する。
生成された Critical CSS が不完全な場合、モバイルでのレイアウトが崩れる。一度「クリティカル CSS を再生成」ボタンで再生成し、それでも改善しない場合は、この機能自体をいったん無効化して様子を見る。
CSS 縮小化(Minify)と結合の影響を切り分ける
「未使用 CSS の削除」を無効にしても問題が続く場合、CSS 縮小化(Minify CSS)または CSS 結合(Combine CSS)が原因である可能性を調べる。どちらか一方だけを有効にしてキャッシュを削除し、崩れの有無を確認する。縮小化と結合を両方有効にしていると切り分けができないため、必ず一方ずつ試す。
原因となる機能を特定できたら、その機能だけを無効化するか、次項で説明する除外設定を使って該当 CSS だけを最適化対象から外す方法に進む。
モバイル用 CSS を WP Rocket の最適化から除外する方法

テーマやプラグインが読み込むモバイル用 CSS ファイルを特定し、WP Rocket の除外リストに追加すれば、最適化によるレイアウト崩れを防ぎつつ、他のファイルの高速化は維持できる。
どの CSS ファイルが除外対象かを特定する
ブラウザのデベロッパーツール(F12)でモバイル表示を開き、「ネットワーク」タブで読み込まれている CSS ファイルを確認する。レスポンシブ用のスタイルを含むファイル名には responsive mobile tablet などの文字列が含まれていることが多い。また、テーマのメインのスタイルシート(style.css)の後半に @media ルールが集中している場合は、ファイル全体を除外候補として扱う必要がある。
WP Rocket の除外設定に CSS を追加する
「WP Rocket」→「ファイル最適化」→「CSS ファイル」セクションを開き、「除外する CSS ファイル(Excluded CSS Files)」のテキストエリアに、先ほど特定したファイル名(例: responsive.css mobile.css theme-responsive-min.css)を行単位で入力する。ファイルの URL の一部(例: /themes/my-theme/css/responsive)でも指定できる。
特定の CSS の塊(インラインの @media ブロックなど)だけを除外したい場合は、「未使用 CSS の削除」の設定内にある「セーフリスト(Safe list)」にクラス名や ID を追加する方法も有効だ。たとえば .mobile-menu #responsive-nav .hamburger など、モバイル表示でのみ使われるセレクタをカンマ区切りで指定すれば、そのルールは削除されずに残る。
Cloudflare 側の設定との競合を防ぐ
Cloudflare の「速度」→「最適化」→「Auto Minify」で CSS と JS の縮小化が有効になっている場合、WP Rocket の縮小化と二重がけになって CSS が破損することがある。Cloudflare 側の CSS 縮小化は無効にし、WP Rocket に一本化する。また Cloudflare の「Rocket Loader」も JavaScript の実行順序を変更するため、モバイルでの動的なスタイル適用に悪影響を及ぼす可能性がある。問題が解消しない場合は Rocket Loader も一時的に停止して検証する。
よくある質問
WP Rocket の「モバイルキャッシュ」機能は有効にすべきか
レスポンシブテーマを使っている場合は「モバイルキャッシュを有効にする(Enable caching for mobile devices)」はオフのままで問題ない。この機能はモバイル専用の別テーマ(例:Jetpack のモバイルテーマ)を使っている場合に必要になる設定で、通常のレスポンシブサイトでは有効化するとキャッシュが二重管理されて意図しない表示になることがある。
CSS 縮小化で改行が消えてレイアウトが崩れることはあるか
改行や空白の除去自体が CSS の意味を変えることはほとんどない。ただし、コメント行に書かれた条件付きブラウザ指定(/*! normalize.css */ のような特殊構文)や、不適切に記述された @import 文が縮小化で破損することがある。その場合は該当ファイルを縮小化の除外リストに追加する。
Remove Unused CSS をオフにするとサイト速度は大幅に落ちるか
ページ全体の CSS サイズが極端に大きい場合を除き、体感速度が大きく落ちることは少ない。むしろレイアウト崩れによるユーザー離脱のリスクのほうが深刻だ。未使用 CSS の削除を無効化したうえで、Critical CSS の生成だけを有効にすると、ファーストビューの表示速度を保ちつつ安定したレイアウトを維持できる。
モバイルキャッシュを削除しても直らないのはなぜか
WP Rocket のキャッシュ削除に加えて、Cloudflare のキャッシュ、ブラウザキャッシュ、サーバー側のページキャッシュ(Nginx FastCGI や LiteSpeed Cache など)のいずれかに古いデータが残っている可能性がある。すべてのキャッシュ層を順にクリアしてからシークレットモードで確認する。また、CDN のエッジサーバーにキャッシュが残っている場合もあるため、Cloudflare の「キャッシュ」→「すべてをパージ」を実行したあと最低5分は待ってから検証する。
この記事のポイント
- モバイルレイアウト崩れの主因は「未使用 CSS の削除」と Critical CSS の不完全な生成
- 問題の CSS を特定し WP Rocket の除外リストに登録すれば最適化と両立できる
- Cloudflare の Auto Minify や Rocket Loader との二重がけに注意する
- キャッシュの検証は全キャッシュ層をクリアしたうえでシークレットモードで行う
- モバイルキャッシュ機能はレスポンシブテーマではオフでよい

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

QSMプラグイン更新後にメディア画面のレイアウトが崩れた時の直し方
特定のプラグインを更新した直後にメディアアップロード画面のレイアウトが崩れた場合、まず該当プラグインのバージョンを更新前の状態に巻き戻すまたは一時的に無効化し、公式サポートへ報告するのが最も早い解決策だ。根本原因はプラグインが管理画面に読み込む CSS や JavaScript の競合にあり、プラグイン側の修正を待つ必要がある。
なぜ QSM プラグインの更新後にレイアウトが崩れるのか

プラグインのバージョンアップでメディアアップロード画面に限って表示が崩れる現象は、Quiz And Survey Master(QSM)v11.1.1 で報告されている。このバージョンで管理画面の他ページ向けに追加された CSS や JavaScript が、メディアライブラリのモーダルやグリッドレイアウトと競合するケースが主な原因だ。
WordPress の管理画面では複数のプラグインが同じ画面にスタイルを適用できる。あるプラグインが独自のフォーム用スタイルをグローバルに出力した場合、メディアアップローダーのドラッグ&ドロップ領域やサムネイル一覧の幅計算が崩れ、ボタンが画面外に飛び出したり画像が縦一列に並んだりする。
この問題は QSM 側が読み込む管理画面用 CSS のセレクタ範囲が広すぎることに起因する。プラグイン開発者が自プラグインの設定画面だけに限定してスタイルを当てるつもりが、WordPress 全体の管理画面に影響するセレクタを使ってしまうことで発生する。
QSM を最新にしたままレイアウト崩れを直す方法

QSM プラグインに依存しているサイトでは単純な無効化が難しいため、まずはプラグイン公式の修正を待ちつつ、以下のいずれかの方法で一時的にレイアウトを正常化できる。
過去の安定バージョンに巻き戻す
WordPress ではプラグインのバージョンを手動でダウングレードできる。まず管理画面の「プラグイン」から QSM を一度削除する。削除してもアンケートデータや設問はデータベースに残る。
次に QSM の公式プラグインページ下部にある「以前のバージョン」 から v11.1.0 以前の安定版 ZIP を入手し、「プラグイン」→「新規追加」→「プラグインのアップロード」でインストールする。有効化後、メディアアップロード画面を再読込すればレイアウトは戻る。
このデモはレイアウト崩れが発生した際の切り分けとバージョン巻き戻しの流れを示している。プラグイン削除で既存データが消える心配はなく、過去バージョンの再適用で一時的に運用を継続できる。
管理画面の特定ページだけで無効化するコードを使う
QSM を有効にしたまま管理画面のメディアページだけでプラグインのスタイルを外したい場合、functions.php にフィルターフックを追加する方法がある。テーマの functions.php や Code Snippets プラグインを用いて以下のコードを追加する。
add_action('admin_enqueue_scripts', function($hook) {
if ('upload.php' === $hook || 'media-new.php' === $hook) {
wp_dequeue_style('qsm-admin-style'); // 実際のハンドル名に応じて変更
}
}, 100);上記の qsm-admin-style は実際に登録されているスタイルシートのハンドル名に置き換える必要がある。ハンドル名は QSM のプラグインソースコードを確認するか、ブラウザの開発者ツールで読み込まれている CSS ファイルの ID 属性から特定できる。
この方法はプラグインのアップデートでハンドル名が変わると再設定が必要になるため、あくまで暫定対応として位置づけるのが現実的だ。
自動更新を一時停止して様子を見る
プラグインの自動更新が有効になっている環境では、意図しないバージョンアップで管理画面が壊れるリスクが常にある。QSM を v11.1.0 に戻したら、プラグイン一覧で QSM の「自動更新を有効化」のチェックを外しておく。WordPress 本体の「更新」画面からも状況を監視し、次期バージョン v11.1.2 以降で修正パッチがリリースされたタイミングで手動更新する方が安全だ。
根本解決のためにすべきこと

レイアウト崩れが特定のプラグインに起因することが分かったら、積極的にプラグイン開発者へ報告するのが最も建設的な対応だ。QSM の公式サポートフォーラムや GitHub リポジトリで、以下の情報を添えて報告すれば修正が加速する。
- 現象が起きた WordPress のバージョンと PHP バージョン
- QSM のバージョン(v11.1.1)
- メディアアップロード画面のスクリーンショット
- ブラウザの開発者コンソールに表示された JavaScript エラー
開発者コンソールの確認方法は、Google Chrome の場合、Windows では F12 キー、Mac では Cmd + Option + I で「Console」タブに切り替え、赤字で表示されたエラーをキャプチャする。
開発者にとってコンソールエラーと発生条件の詳細は修正箇所を特定する決定的な手がかりになる。報告するときは感情的な内容を避け、「メディアページを開いたときだけレイアウトが崩れる。コンソールには ○○ というエラーが出ている」と具体的に伝えるとよい。
よくある質問
プラグインを無効化せずにメディアアップロードだけ使う方法はあるか
投稿画面の「メディアを追加」ボタンからもファイルをアップロードできる。メディアライブラリのグリッド表示が崩れていても、このモーダル画面では正常に動作するケースが多い。
QSM が原因かどうかを確実に特定するにはどうすればいいか
最も確実なのは Health Check & Troubleshooting プラグインを使ったトラブルシューティングモードだ。このモードではログイン中の自分だけにプラグインの無効化が適用されるため、サイト訪問者には影響を与えずに QSM のオンオフを切り替えられる。
バージョンを戻すとアンケートのデータは消えるのか
消えない。QSM の設問や回答データはデータベースの専用テーブルに保存されている。プラグインを削除しても WordPress の標準動作ではテーブルが削除されないため、再インストール後にすべてのデータが復元される。
子テーマの functions.php を編集するのが不安だ
Code Snippets プラグインを使えば管理画面から安全に PHP コードを追加できる。文法エラーがあるとスニペットが自動で無効化されるため、サイト全体が真っ白になるリスクを回避しやすい。
今回の問題は WordPress 本体のせいか
違う。WordPress 本体の更新ではなく、QSM プラグインの特定バージョン(v11.1.1)が原因だ。WordPress コアにはメディア画面のレイアウトに関する既知の不具合は報告されていない。
この記事のポイント
- QSM v11.1.1 への更新が原因でメディアアップロード画面のレイアウトが崩れる
- 即効対策は v11.1.0 以前の安定版に巻き戻すこと
- 暫定対策として functions.php で特定ページだけスタイルを停止できる
- 恒久解決にはプラグイン開発者への詳細なエラー報告が不可欠
- 自動更新を停止して次期バージョンでの修正を待つのが安全

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

WooCommerce処理中注文を未払いのまま請求書プラグインに連携する方法
WooCommerceで銀行振込(BACS)や後払い決済を使う場合、注文を「処理中」にした途端に、外部の請求書発行プラグインがその注文を「支払い済み」と認識してしまうことがある。この原因は、WooCommerceが処理中ステータスに遷移する際に支払い日(_date_paid)を自動で記録し、多くのプラグインがそのメタデータを支払い完了の合図として読み取るからだ。ここではこの仕組みを詳しく解説し、後払い注文を未払いのまま連携させる確実な修正方法を紹介する。
なぜ処理中になった注文が「支払い済み」扱いになるのか

WooCommerceの内部動作として、注文が「処理中(processing)」または「完了(completed)」に切り替わると、maybe_set_date_paid()というメソッドが呼ばれ、現在の日時を_postmetaテーブルの_date_paidに保存する。この動作は、クレジットカード決済など即時払いが完了した瞬間を記録するためにある。ところが銀行振込(BACS)は標準で「保留中(on-hold)」になるが、運用上「処理中」に手動変更したり、コードで処理中に固定すると、実際には入金前でも支払い日が書き込まれてしまう。
請求書発行プラグイン(WooCommerce PDF Invoicesや会計連携プラグインなど)は、通常この_date_paidをもとに「支払い済み」かどうかを判断する。さらに、WC_Orderクラスのis_paid()メソッドは内部的に「処理中」「完了」といったステータスを見てtrueを返す設計のため、_date_paidが空でも「支払い済み」と扱われるケースも多い。結果として、入金前の後払い注文が会計ソフト上で「支払い済み請求書」として取り込まれてしまうのだ。
上図のように、_date_paidの書き込みを止めるか、支払い済み判定のロジック自体を書き換えることで、請求書が正しく「未払い」で連携されるようになる。次に、具体的にどう対処すればよいかを方法別に紹介する。
支払い済み判定のメカニズムを特定する

修正に入る前に、自分が使っている請求書発行プラグインがどのタイミングで「支払い済み」と判断しているかを知っておくと無駄な試行錯誤が減る。大きく分けると以下の3パターンがあり、フィルターの効き方が変わる。
- _date_paidのメタデータを直接 get_post_meta() や$order->get_meta(‘_date_paid’) で読み取っている
- WC_Order::get_date_paid() メソッドを呼び出している(フィルターフック posible)
- WC_Order::is_paid() メソッドで判定している(ステータスベース)
多くのプラグインは最後のis_paid()や、直接メタデータを読む形をとる。get_date_paid()フィルターだけでは直らなかった場合、is_paid()の返り値を書き換えるか、そもそも_date_paid自体を保存させないアプローチが有効だ。
強制的に未払いにする3つの方法

方法1. _date_paidが記録されるのを根本から防ぐ
WooCommerceが処理中ステータスに変わったときに_date_paidをセットするのは、maybe_set_date_paid()の中で「このステータスは支払い完了とみなす」という配列に「processing」が含まれているからだ。この配列はwoocommerce_payment_complete_order_statusフィルターで変更できる。以下のコードをテーマのfunctions.phpまたはCode Snippetsプラグインで追加すれば、BACS(bank transfer)決済の注文でのみ「processing」を支払い完了ステータスから外せる。
add_filter('woocommerce_payment_complete_order_status', function($statuses, $order) {
if ($order instanceof WC_Order && 'bacs' === $order->get_payment_method()) {
$statuses = array_filter($statuses, function($s) {
return $s !== 'processing';
});
}
return $statuses;
}, 10, 2);これにより、BACSの注文が「処理中」に移行しても、WooCommerceは「これは支払い完了ステータスではない」と認識し、_date_paidを一切書き込まない。注文メモなどに残る変わったログも出ず、動作は非常にクリーンだ。結果として、請求書プラグインが_date_paidを見ている限り、未払いのままとなる。
方法2. is_paid()の返り値を上書きする
もし日付メタデータを消してもなお請求書が「支払い済み」になってしまう場合は、プラグインがWC_Order::is_paid()メソッドを使っている可能性が高い。このメソッドは内部的にwc_get_is_paid_statuses()が返すステータス配列(デフォルトでは’processing’と’completed’)と照合し、trueを返す。こちらもフィルターでBACSだけ処理中を除外できる。
add_filter('woocommerce_order_is_paid_statuses', function($statuses, $order) {
if ($order instanceof WC_Order && 'bacs' === $order->get_payment_method()) {
$statuses = array_diff($statuses, array('processing'));
}
return $statuses;
}, 10, 2);このコードを追加すると、is_paid()は見かけ上「処理中」でもfalseを返すため、請求書プラグインは「未払い」と判断する。方法1と併用すれば、_date_paidの直接読み取りもis_paid()経由の判定も両方ブロックできる。
方法3. プラグイン側のエクスポートフィルターを利用する
どうしても上記のフィルターで直らない、あるいは他プラグインとの兼ね合いで処理中ステータスを支払い完了扱いのままにしたい場合は、請求書発行プラグインが用意しているデータ書き換え用のフックを使う。たとえば、WooCommerce PDF Invoices & Packing Slips であれば wpo_wcpdf_document_data や wpo_wcpdf_invoice_data といったフィルターがある。請求書に含める「支払い済み」フラグや日付を、注文の支払い方法がBACSのときだけ空にすることで解決できる。
プラグインのフィルター一覧は開発元のドキュメントで確認する必要があるが、一般に「Paid = 1」や「paid_date」といったキーを書き換えることが多い。次のサンプルは、WooCommerce PDF Invoicesで支払い状況を未払いに戻す例だ。
add_filter('wpo_wcpdf_invoice_data', function($data, $document) {
if ($document->order instanceof WC_Order && 'bacs' === $document->order->get_payment_method()) {
$data['paid'] = 0;
$data['date_paid'] = '';
}
return $data;
}, 10, 2);なお、プラグインが読み取るフィールド名は製品によって異なるため、実際のソースコードや開発元への問い合わせで正確なキー名を調べるのが確実だ。
カスタム注文ステータスで処理中と区別する方法

根本的に「後払い専用の処理中ステータス」をWooCommerceに追加するという手もある。標準の処理中ステータスは、支払い完了後の発送準備として使われる場面が多い。これに対し、後払いは「入金確認前だが、すでに注文を受け付け、請求書を発行したい」という微妙な状態だ。そこで「後払い処理中」のようなカスタムステータスを作れば、WooCommerceの支払いロジックに干渉せず、かつ請求書プラグインも処理中ではないため誤って支払い済み扱いしなくなる。
function register_custom_order_status_invoice_processing() {
register_post_status('wc-invoice-processing', array(
'label' => '後払い処理中',
'public' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop('後払い処理中 (%s)', '後払い処理中 (%s)')
));
}
add_action('init', 'register_custom_order_status_invoice_processing');
add_filter('wc_order_statuses', function($order_statuses) {
$order_statuses['wc-invoice-processing'] = '後払い処理中';
return $order_statuses;
});
このステータスをBACSの注文に割り当てれば、標準の処理中ルートを通らずに済む。ただし、配送プラグインや在庫連動がこのカスタムステータスを「処理中」同様に扱うよう追加のフックが必要になるケースもある。その場合は、woocommerce_order_is_paid_statusesフィルターなどで「wc-invoice-processing」も支払い完了とみなしたい処理にだけ含めると調整できる。
よくある質問
この修正を適用すると、クレジットカードの処理中注文まで未払いになりませんか
紹介したコードはいずれも if 文で’ bacs ‘決済に限定しているため、クレジットカードや他の即時決済には影響しない。条件を厳密に書けば、安全に導入できる。
後払い注文のステータスをカスタムステータスにしたら、WooCommerceの標準メールは飛びますか
新規ステータスを追加しただけでは自動的にメールは送信されない。woocommerce_order_status_invoice-processing のようなアクションフックを利用して、独自のメールテンプレートをトリガーするか、処理中と同じメールを送るように設定する必要がある。
どの方法を選ぶべきかの判断基準は
まずは方法1と方法2を組み合わせて適用してみるのが最も手軽で汎用性が高い。それで解決しない場合はプラグイン固有のフィルターを探す。長期的に後払いワークフローを整理したいならカスタムステータスがおすすめだ。
この記事のポイント
- 処理中へのステータス変更で_date_paidが自動保存される仕様が原因
- woocommerce_payment_complete_order_statusフィルターで_date_paid書き込みをBACSだけ無効化できる
- is_paid()の返り値を上書きすれば、日付以外の「支払い済み」判定もブロック可能
- 請求書プラグイン固有のフィルターがあれば、そこからも支払い情報を空にできる
- 後払い専用のカスタム注文ステータスを導入すれば、処理中と混同せずに管理できる

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている

Diviポップアップを時間指定で自動表示するトリガー設定方法
Divi のポップアップを「ページを開いてから数秒後」や「一定のスクロール後」に自動表示するには、ポップアップ編集画面のトリガー設定を使う。Divi ビルダーで作成したポップアップであれば、標準機能だけで時間遅延やスクロール位置を細かく制御できる。プラグイン版のポップアップ機能を使っている場合でも、設定タブの名称こそ異なるが考え方は同じだ。
Divi ポップアップのトリガー設定を開く手順

まずは、すでに作成済みのポップアップの編集画面にアクセスする。WordPress 管理画面の「Divi」メニューから「Theme Builder」を開き、登録されているポップアップの一覧を表示する。該当のポップアップをクリックすれば、Divi ビルダーの編集画面が立ち上がる。
ポップアップの編集画面では、画面下部にある「設定」パネルの中に「トリガー」タブが存在する。ここが表示タイミングを決める中核部分だ。もし「トリガー」タブが見当たらない場合は、ポップアップを新規作成したときに「ポップアップの種類」を誤って選択した可能性がある。再度ポップアップの種類を確認し、「自動ポップアップ」など時間経過に対応した種類を選び直す必要がある。
ページ表示後の時間でポップアップを表示する手順

トリガー設定内で「時間遅延」を選択し、秒数を指定するのが最もシンプルな方法だ。ここでは具体的な操作の流れと、設定値の意味を明確にする。
時間遅延のトリガーを正確に設定するコツ
時間遅延のプルダウンを選ぶと、すぐ下に「遅延時間(秒)」という入力欄が現れる。ここに数字(半角)を入れるだけで、ページが完全に読み込まれてからその秒数が経過した時点でポップアップが出現する。
たとえば「5」と入力すれば、ユーザーがページにアクセスして5秒後に表示される。なお、この秒数は外部スクリプトや画像の読み込み完了を基準にするため、重いページでは体感より若干遅れることがある。3〜8秒程度の短めの数字にしておくと、ユーザーがページを離れる前に目に留まりやすい。
複数のトリガーを同時に有効化できることも覚えておきたい。時間遅延とスクロールを併用すれば「5秒経過、かつ 30% スクロールしたら表示」といったより複雑な条件も作れる。
スクロール量でポップアップを表示する手順

スクロールをトリガーにする場合は、同じ「トリガー」タブ内で「スクロール」を選択する。ページの何パーセントがスクロールされた時点で表示するかを、スライダーまたは数値入力で指定できる。
スクロールトリガーのパーセント設定の考え方
スクロール量の入力値は「ページ全体の高さに対する比率」を示す。たとえば 25% と設定すれば、ユーザーがページの4分の1までスクロールしたタイミングでポップアップが出現する。記事ページなど長いコンテンツでは 40〜60% に設定すると、読み進めたユーザーにだけ訴求でき、直帰率の高いユーザーを無駄に邪魔しない。
注意点として、ページの高さが極端に短い場合(例えばランディングページなど)、設定したパーセントに到達する前に画面外に出てしまい、ポップアップが表示されないことがある。そうしたページではパーセントを低めに調整するか、時間遅延との併用を検討するとよい。
設定したポップアップが表示されないときのチェックポイント

トリガーを正しく設定しているのに実際のページでポップアップが出てこない場合は、いくつかの典型的な原因を順に潰していく。
- キャッシュの影響を受けている。Divi の設定を変更したら、サーバー側キャッシュやブラウザキャッシュをクリアする。
- 表示条件(ポップアップが表示されるページのルール)が合っていない。特定のページのみに制限していないか確認する。
- ブラウザのポップアップブロッカーが反応している。Divi のポップアップは HTML/CSS ベースなので通常は影響を受けないが、拡張機能の干渉を疑う。
- JavaScript の競合が起きている。他のプラグインやテーマのスクリプトと衝突し、トリガーが発火していない可能性がある。全プラグインを一時停止して切り分ける。
特にキャッシュ系プラグインを使用している場合は、Divi の JavaScript ファイルが古いまま配信されているケースが多い。キャッシュを削除したうえでシークレットウィンドウからアクセスすれば、新鮮な状態で動作確認ができる。
よくある質問
時間遅延とスクロールの両方を同時に使えるか
Divi のポップアップ設定では、トリガータイプを複数組み合わせることができる。時間遅延とスクロールの両方をアクティブにすると「指定秒数が経過した、かつ指定のパーセントまでスクロールした」時にのみポップアップが表示される AND 条件になる。どちらか一方だけで十分なケースが多いが、コンバージョンを高めたいランディングページでは組み合わせも有効だ。
モバイル端末ではポップアップを非表示にできるか
「トリガー」タブの下にある「表示設定」セクションで、デバイスごとの表示オンオフを切り替えられる。モバイルのチェックを外せば、スマートフォンやタブレットでは一切ポップアップが表示されなくなる。画面サイズが小さい端末でポップアップが邪魔にならないようにするために、多くのサイトでこの設定が使われている。
ポップアップが何度も出るのを防ぐには
一度表示したポップアップを同じユーザーに再度表示しないようにするには、「表示設定」の「頻度」オプションを使う。「セッションごとに1回」や「日ごとに1回」などを選べば、Cookie によって表示回数を制限できる。時間遅延で表示するポップアップであっても、この設定を併用すればユーザー体験を損ねにくい。
ポップアップにカウントダウンタイマーを表示したい
Divi には標準でカウントダウンタイマーモジュールが用意されている。ポップアップのレイアウト内にそのモジュールを配置すれば、表示と同時にタイマーが動き始める。時間遅延のトリガーと組み合わせると「あと○秒で閉じます」といった演出も可能だ。なお、タイマーはサーバー時刻ではなくブラウザ側で動作するため、正確な時刻に基づくキャンペーンには向かない。
この記事のポイント
- Divi ポップアップの表示タイミングは「トリガー」タブで設定する
- 時間遅延は秒数、スクロールはパーセントで指定できる
- キャッシュや表示条件が原因で動作しないことが多いのでまず確認する
- モバイル非表示や表示頻度制限を併用するとユーザーに優しい

・ Reddit、Stack Overflow、WordPress.org フォーラムを日々巡回し、現場の悩みを拾い上げて記事化
・ WordPress、WooCommerce、Next.js などモダンWeb制作領域のトラブルシューティングが専門
・ 「検索しても答えが見つからなかった」を一つでも減らすことが目標
・ エラーメッセージから根本原因にたどり着く粘り強い調査が得意
・ 初心者がつまずきやすい箇所を先回りで解決する記事作りを心がけている
