月別アーカイブ 2026年6月23日

WooCommerceアナリティクスでOops something went wrongエラーが出た時の直し方

WooCommerceアナリティクスでOops something went wrongエラーが出た時の直し方

WooCommerce を 10.6.1 にアップデートした直後、アナリティクス概要に「Oops something went wrong」と表示され、ブラウザコンソールに TypeError: t(…)(…).tz is not a function というエラーが記録される場合、JavaScript のタイムゾーンライブラリを巡るプラグイン競合か、キャッシュの不整合が原因だ。まず全プラグインの無効化と標準テーマへの一時的な切り替えで原因を特定し、競合するプラグインを見つけ出すことから始める。

なぜ WooCommerce アナリティクスで tz is not a function エラーが起きるのか

WooCommerce の管理画面アナリティクスは、内部的に Moment.js とそのタイムゾーン拡張を使い、日付や時間の演算をおこなっている。10.6.1 では JavaScript アセットの読み込み順や依存関係に変更が入ったため、別のプラグインやテーマが同じ Moment.js タイムゾーンライブラリを異なるバージョンで読み込んでいる場合に .tz メソッドが上書きされるか、存在しない状態になり、今回の TypeError が発生する。

また、ブラウザやサーバー側のキャッシュに古いスクリプトが残っていると、管理画面で本来動くはずの新しいコードと混ざり、同様のエラーが出ることもある。まずは「どの拡張機能やテーマが影響しているか」を切り分けるのが近道だ。

エラーの原因を特定する手順

エラーの原因を特定する手順
STEP 1 WooCommerce を残して 全プラグインを無効化する
STEP 2 テーマを Storefront または Twenty Twenty-Five に一時的に切り替える
STEP 3 ブラウザキャッシュ、サーバーキャッシュ、WP キャッシュをすべてクリアする
STEP 4 アナリティクスを開いてエラーが消えたら、プラグインを1つずつ再有効化して原因を特定する

上図の手順で、問題の切り分けができる。WooCommerce 本体だけを有効にした状態でアナリティクスが正常に動けば、あとは再有効化の過程でエラーを再現させるプラグインを見つければよい。

全プラグインを無効化して競合を確認する

「プラグイン」→「インストール済みプラグイン」画面で、全てのプラグインにチェックを入れ、「一括操作」から「停止」を実行する。WooCommerce だけは残すか、最初はすべて停止し、その後 WooCommerce だけ有効化し直す。この状態で管理画面の「WooCommerce」→「アナリティクス」を開き、エラーが出ないか確認する。

テーマを Storefront など標準テーマに切り替える

有効化しているテーマの functions.php やフックが、管理画面の JavaScript 読み込みに干渉しているケースは意外に多い。「外観」→「テーマ」で Storefront や Twenty Twenty-Five など公式の軽量テーマに一時的に切り替え、同じくアナリティクス画面を確認する。

ブラウザキャッシュとサーバーキャッシュをすべて削除する

キャッシュ系プラグイン(W3 Total Cache、WP Rocket など)を使っている場合は管理画面からキャッシュを全削除する。さらにブラウザでシークレットウィンドウ(プライベートブラウジング)を開き、そちらで管理画面にログインしてテストすると、ローカルキャッシュの影響を排除できる。サーバー側で OPcache や Redis オブジェクトキャッシュを導入している場合は、それらのクリアもおこなう。

プラグインを1つずつ再有効化して原因を突き止める

無効化状態でエラーが消えたら、プラグインを1つ有効化するごとにアナリティクス画面を再読み込みし、エラーの再発をチェックする。再現したプラグインが競合元だ。よくあるのは、カスタムレポート系、日付や予約管理、多言語対応(WPML や Polylang)、ページビルダーの管理画面用スクリプトを追加するタイプのプラグインだ。

競合するプラグインを特定したあとの恒久対策

競合するプラグインを特定したあとの恒久対策

原因のプラグインが判明しても、サイト運営上どうしても外せない場合がある。そのときは、問題のスクリプトだけを管理画面のアナリティクスページでのみ読み込まないようにする手がある。

以下のコードを子テーマの functions.php に追加すると、特定のスクリプトをアナリティクス画面で解除できる。ここでは例として「moment-timezone」ハンドルを一旦解除し、WooCommerce が想定する正しいバージョンを再登録する方法を示す(実際のハンドル名は競合元により異なるため、ブラウザのデベロッパーツールで確認する)。

add_action( 'admin_enqueue_scripts', function( $hook ) {
    if ( false === strpos( $hook, 'woocommerce_page_wc-analytics' ) ) {
        return;
    }
    wp_dequeue_script( 'moment-timezone' );
    wp_deregister_script( 'moment-timezone' );
    wp_enqueue_script( 'moment-timezone', includes_url( 'js/moment-timezone.min.js' ), array( 'moment' ), null, true );
}, 100 );

この例では WordPress 本体バンドルの moment-timezone を読み直しているが、WooCommerce が読み込むパスとは異なる場合がある。より安全なのは、競合プラグイン側の更新を待つか、Asset CleanUp 系のプラグインで該当スクリプトを該当ページでのみブロックする方法だ。

それでも直らない場合の応急処置としての WooCommerce のロールバック

どうしてもすぐにエラーを止めたいときは、WooCommerce を問題のなかったバージョン(例:10.5.2)に戻す方法がある。無料プラグイン「WP Rollback」を使えば、管理画面からワンクリックで以前のバージョンにダウングレードできる。

「プラグイン」→「新規追加」で WP Rollback をインストールし有効化すると、プラグイン一覧の WooCommerce に「ロールバック」リンクが現れる。そこから 10.5.2 を選択し、ロールバックを実行する。ただし、これは一時しのぎであり、セキュリティ修正などが含まれている場合はリスクがあるため、問題の根本解決を優先する。

よくある質問

プラグインをすべて無効化してもエラーが消えないのはなぜか

テーマの functions.php や子テーマに管理画面用のスクリプトを追加している可能性が高い。必ず標準テーマ(Storefront や Twenty Twenty-Five)に切り替えて確認する。また、ブラウザ拡張機能やサーバー側のキャッシュが残っている場合もエラーが継続する。

キャッシュを削除しても改善しない場合はどうするか

ブラウザのシークレットウィンドウを使うか、別のブラウザでテストする。サーバー側で OPcache や Varnish、CDN のキャッシュが効いている場合は、そちらも合わせてクリアする。WP CLI が使えるなら wp cache flush も試す。

特定のプラグインが原因とわかったが、そのまま使い続けたい

プラグイン開発元に WooCommerce 10.6.1 への対応状況を問い合わせ、アップデートを待つのが最も確実だ。緊急時は、前述のコード例や Asset CleanUp で競合を回避する方法があるが、サイト全体の動作確認を十分におこなったうえで適用する。

WooCommerce をダウングレードしても問題ないか

ダウングレードすると、10.6.1 で修正されたセキュリティ上の問題や不具合が再発する可能性がある。あくまで原因究明と修正が終わるまでの一時的な措置と考え、早急に恒久対策を講じる。

同じエラーがフロントエンドのカートやチェックアウトでも出る

管理画面だけでなくフロントエンドでも同様の TypeError が発生する場合、テーマかキャッシュプラグインの JavaScript 最適化機能(結合・圧縮)が原因になっていることが多い。キャッシュプラグインの設定で JavaScript の結合を一時的に無効にし、テーマを標準テーマに切り替えて症状が消えるか確認する。

この記事のポイント

  • WooCommerce 10.6.1 でアナリティクスに tz is not a function エラーが出るのは JavaScript のタイムゾーンライブラリ競合かキャッシュ不整合
  • プラグイン全無効化+標準テーマへの切り替えで原因を特定し、1つずつ再有効化して競合プラグインを特定する
  • 競合プラグインが見つかったら、更新を待つか functions.php でスクリプトを制御する
  • 緊急時は WP Rollback で WooCommerce を一時的にダウングレードできるが、恒久対策が優先
Astro 7.0リリース、Rustコンパイラでビルド時間を最大61%短縮

Astro 7.0リリース、Rustコンパイラでビルド時間を最大61%短縮

Astro 7.0が6月22日に正式リリースされた。今回のメジャーアップデートは「速度」にフォーカスしており、.astroファイルのコンパイラをRustで書き直した点が最大の変更点だ。

ベンチマークによると、ビルド時間は前バージョンと比較して15〜61%短縮される。Astro公式ブログが公開したテスト結果では、13,275ページを持つaspire.devのビルドが半分以下になった事例も報告されている。Rust化された基盤、Vite 8との統合、新しいアドバンストルーティング機能が主要な柱だ。

本記事ではAstro 7.0の全変更点を、実務者の視点から詳しく解説する。

Vite 8によるバンドル基盤の刷新

Vite 8によるバンドル基盤の刷新

Astro 7.0のビルド高速化を支える土台が、Vite 8へのアップグレードだ。Vite 8は、JavaScriptツールチェインの世界で最も注目されているリリースのひとつである。最大の変更点は、Rustベースのバンドラ「Rolldown」が標準搭載されたことだ。

Rolldownとは何か

Rolldownは、従来のesbuildとRollupを単一のバンドラで置き換えるツールである。バンドラとは、複数のJavaScriptファイルやコンポーネントを本番用の少数のファイルにまとめる役割を持つ。Rolldownのベンチマークでは、Rollupと比較して10〜30倍高速という結果が出ている。速度だけでなく、既存のRollupプラグインAPIとの互換性も維持している点が実務上の大きな利点だ。

Astroユーザーにとって重要なのは、ほとんどのプロジェクトで設定変更が不要なことだ。Vite 8には既存のesbuild設定やrollupOptions設定を自動的にRolldown用に変換する互換レイヤーが組み込まれている。カスタムViteプラグインを使っている場合も、RolldownがRollupと同じプラグインAPIをサポートするため、そのまま動作する可能性が高い。

Rust化がもたらすビルド性能の飛躍的向上

Rust化がもたらすビルド性能の飛躍的向上

Astroのビルドプロセスは、大きく2つの段階に分かれる。1つ目はサイトのページやコンテンツ、クライアントコンポーネントをJavaScriptにバンドルする段階。2つ目は、バンドルされたコードを「小さなサーバー」として実行し、プリレンダリング対象の全ページにリクエストを送ってHTMLを生成する段階だ。

Astro 7.0は両方の段階を改善しているが、とくに1つ目のバンドル段階に注力している。ビルド時間のボトルネックになりやすい処理をRustで書かれたネイティブコードに移行することで、大幅な高速化を実現した。

Astro 6.x のビルドフロー
.astro ファイル Go製 コンパイラ unified (Markdown処理) Recursive レンダリング
Markdown処理はJavaScriptベースで数千ページ規模だと大きなボトルネックに
Astro 7.0 のビルドフロー
.astro ファイル Rust製 コンパイラ (oxc/Lightning CSS) Sätteri (Rust製Markdown処理) キュー型レンダリング
Rust化+Vite 8 (Rolldown) の組み合わせで15〜61%のビルド時間短縮

上図の通り、ビルドフローの主要な構成要素がRustベースに置き換えられている。.astroファイルのコンパイル、Markdown/MDXの処理、レンダリングエンジンのすべてが刷新された。以下では各要素を詳しく見ていく。

.astroコンパイラのRust化

Astro 7.0では、.astroコンポーネント形式の新しいコンパイラがRustで構築された。このコンパイラは、以前のGoベースのコンパイラをフルリライトしたものだ。内部的には、oxc(高速なJavaScript/TypeScriptパーサ)を解析に、Lightning CSSをCSSスコープ処理に使っている。

単体ではビルド時間の約6%改善にとどまるが、数千ページ規模の大規模サイトでは、他の改善と相乗効果を発揮する。以下の3点は後方互換性に関わる変更として注意が必要だ。

  • HTML自動修正の廃止。旧コンパイラは「正しいHTML」にしようと要素の並べ替えやタグの自動クローズを行っていたが、新コンパイラではマークアップをそのまま扱う。予期せぬ挙動の原因だった自動修正がなくなり、意図した通りに出力されるようになった。
  • JSX形式の厳格化<div>Helloのような閉じタグ欠落や、<div class="Hello >のような属性の未終端は、自動修正されずエラーになる。旧コンパイラがブラウザの挙動を真似て黙って修正していた部分だ。
  • JSXホワイトスペース処理。インライン要素間の改行が可視スペースを生成しなくなる。たとえば、<span>Hello</span><span>World</span>は「HelloWorld」と表示される。スペースが必要な場合は{' '}を明示的に挿入する。

Markdown/MDX処理のSätteri移行

Astro 7.0では、デフォルトのMarkdownとMDXの処理パイプラインが、Rust製プロセッサ「Sätteri」に置き換えられた。SätteriはAstroコアチームメンバーが開発したツールで、内部的にはpulldown-cmark(CommonMark解析)とoxc(MDX式解析)を使用している。

従来のAstroは、JavaScriptベースのunified(remark/rehypeとそのプラグイン群)でMarkdownを処理していた。数千ページのサイトでは、このパイプラインがビルドの最も遅い段階になることが多かった。Astro公式ブログによれば、AstroドキュメントサイトとCloudflareドキュメントサイトでSätteriに切り替えたところ、ビルド時間が1分以上短縮されたという。

Sätteriには、これまで別途プラグインが必要だったMarkdown機能の多くがビルトインで含まれている。GFM(テーブル、脚注、取り消し線、タスクリスト)、スマートパンクチュエーション(カーリークォート)、見出しID、コンテナディレクティブ、数式、フロントマター(YAML/TOML)、上付き・下付き文字、Wikilinksなどだ。これらはfeaturesオプションで有効化できる。

既存のremark/rehypeプラグインに依存しているプロジェクトは、@astrojs/markdown-remarkを使って従来のunifiedベースのパイプラインを引き続き利用できる。

キュー型レンダリングの安定化

Astro 6.0で実験的機能として導入されたキュー型レンダリングが、Astro 7.0で安定版となりデフォルトのレンダリングエンジンになった。これは、式が密集したページで約2.4倍高速という結果が出ている。

従来のレンダリングは再帰的アプローチを取っていた。親コンポーネントが子コンポーネントを呼び出し、さらにその子が孫を呼び出すという入れ子構造でレンダリングが進む。これに対し、新しいエンジンはキュー(またはスタック)と単一のループを使う。キューに子ノードを正しい順序で追加し、キューが空になるまでループでレンダリングを続ける仕組みだ。

初回の実装では「全コンポーネントの順序付きリストを作成→リストをループしてレンダリング」という2パス方式だったが、最終版ではリスト作成とレンダリングを同時に行う方式に改善された。この方式は再帰的アプローチと比較してメモリ使用量も少ない。

アドバンストルーティングでリクエストパイプラインを完全制御

アドバンストルーティングでリクエストパイプラインを完全制御

Astroは静的サイトジェネレーターとしてスタートし、ファイルベースのルーティングを基本としてきた。しかし、ミドルウェア、リダイレクト、リライト、Actions、セッション、i18nといった機能が追加されるにつれ、リクエストのライフサイクル制御が複雑化していた。

認証をActionsより先に実行したい、ログ出力をページレンダリングだけに限定したい、APIリクエストをAstroの外で先に処理したい、といったニーズに応えるため、Astro 7.0ではsrc/fetch.tsファイルを追加することでリクエストパイプラインを完全制御できるようになった。

このパターンは、Cloudflare WorkersやDeno、Bunが採用している標準的なfetchハンドラ形式に準拠している。

import { astro, FetchState } from 'astro/fetch';

export default {
  fetch(request: Request) {
    const state = new FetchState(request);

    // APIリクエストをバックエンドサービスに転送
    if (state.url.pathname.startsWith('/api')) {
      const url = new URL(
        state.url.pathname + state.url.search,
        'https://backend-api.example.com'
      );
      return fetch(new Request(url, request));
    }

    // それ以外はAstroのページやエンドポイントにフォールバック
    return astro(state);
  }
}

Honoとの統合

アドバンストルーティングAPIはHonoとも互換性がある。Honoは軽量なWebフレームワークで、豊富なミドルウェアエコシステムを持つ。以下のようにBasic認証をAstroアプリケーションに組み込める。

import { astro } from 'astro/hono';
import { Hono } from 'hono';
import { basicAuth } from 'hono/basic-auth';

const app = new Hono();
app.use(basicAuth({ username: 'admin', password: 'secret' }));
app.use(astro());

export default app;
従来のミドルウェア(Before)
i18n Actions ミドルウェア ページ
認証チェックがActionsの後になるため、未認証のアクション呼び出しが発生しうる。レスポンスタイミングのログ出力も個別にラップする必要があった
アドバンストルーティング(After)
i18n 認証 Actions ミドルウェア タイミングログ ページ
認証がActionsより先に実行され、タイミングログはページレンダリングのみをラップする。コードを必要な場所に正確に配置可能

より高度な使い方として、個別のAstro機能を別々のミドルウェアとして構成できる。認証、Actions、ミドルウェア、i18n、ページの各レイヤーを任意の順序で積み重ねられるため、認証チェックをActionsより手前に置くといった制御がシンプルに実現できる。このsrc/fetch.tsファイルを追加しなければ、Astroの動作は従来通りだ。

ルートキャッシングとCDNプロバイダ連携

ルートキャッシングとCDNプロバイダ連携

オンデマンドレンダリング応答のキャッシュ制御は、ホスティングサービスごとに異なる仕組みで実装されてきた。Astro 7.0で安定版となったルートキャッシングは、デプロイ先を問わない単一のキャッシングAPIを提供する。

設定の流れはシンプルだ。まずキャッシュプロバイダを一度設定し、あとはページ内でAstro.cache(APIルートではcontext.cache)を使ってレスポンスごとにキャッシュ制御を記述する。標準的なHTTPキャッシングセマンティクスに従うため、特別な知識は不要だ。

import { defineConfig, memoryCache } from 'astro/config';

export default defineConfig({
  cache: {
    provider: memoryCache(),
  },
});
---
Astro.cache.set({
  maxAge: 120,          // 2分間キャッシュ
  swr: 60,              // 再検証中は1分間 stale を返す
  tags: ['products'],   // タグベースの無効化用
});
---

routeRulesを使えば、ルートグループ単位で宣言的にキャッシュルールを設定できる。

export default defineConfig({
  cache: { provider: memoryCache() },
  routeRules: {
    '/blog/[...path]': { maxAge: 300, swr: 60 },
  },
});

キャッシュの無効化はcache.invalidate()でタグ単位またはパス単位で行える。CMSのwebhookエンドポイントをAstroで実装し、コンテンツ更新時に該当キャッシュを破棄するといった使い方が可能だ。

CDNキャッシュプロバイダ

Astro 7.0では、Netlify、Vercel、Cloudflare向けのCDNキャッシュプロバイダが実験的機能として追加された(Cloudflareはプライベートベータ)。これらはレスポンスをメモリではなく、各プラットフォームのエッジネットワークにキャッシュする。キャッシュヒット時はサーバー関数を呼び出さず、CDNから直接応答が返るため、さらに高速なレスポンスを実現できる。

アダプタごとに/cacheエントリポイントからプロバイダをインポートする。

import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';
import { cacheNetlify } from '@astrojs/netlify/cache';

export default defineConfig({
  adapter: netlify(),
  cache: {
    provider: cacheNetlify(),
  },
});

Astro.cacherouteRulescache.invalidate()のAPIは、どのプロバイダでも同じように動作する。各プロバイダが、Astroのキャッシュディレクティブを各プラットフォームのネイティブなキャッシュ制御ヘッダと無効化APIに変換する仕組みだ。

AIエージェント向け開発サーバー機能

AIエージェント向け開発サーバー機能

AIコーディングエージェントの普及に伴い、Astro 7.0はエージェント駆動開発を支援する機能を導入した。AIエージェントは、終了しない長時間実行プロセス(開発サーバー)の扱いが苦手だ。シェルコマンドを実行し、終了を待って出力を読むワークフローに、開発サーバーは適合しない。

バックグラウンド開発サーバー

astro dev --backgroundコマンドを使うと、開発サーバーを管理されたバックグラウンドプロセスとして起動できる。コマンドはサーバーがリクエストを受け付け可能になるまでブロックし、URLとプロセスIDを出力してからデタッチする。ポーリングやスリープ、端末出力の解析は一切不要だ。

AstroはAIエージェント内で実行されていることを自動検出し、バックグラウンドモードを自動的に有効にする。エージェントワークフローでは--backgroundフラグの指定すら不要だ。

ロックファイルによって重複インスタンスが防止される。エージェントが誤って2つ目のサーバーを起動しようとすると、既存インスタンスの詳細が返される。astro dev statusで状態確認、astro dev stopで停止、astro dev logsでバックグラウンドサーバーのログを確認できる。また、全実行中の開発サーバーは/_astro/statusヘルスエンドポイントを公開し、エージェントがサーバーの生存を確認できる。

JSONログ出力

Astroのロガーが完全に設定可能になった。AIエージェント向けには、バックグラウンドモードの自動検出時にJSONログが自動的に有効化される。それ以外の用途でも、CLIまたは設定ファイルで有効化できる。

astro dev --json
import { defineConfig, logHandlers } from "astro/config";

export default defineConfig({
  logger: logHandlers.json()
})

構造化ログが必要なユースケースはAIだけではない。SSRで本番運用しているチームは、Kibana、CloudWatch、Grafana/Lokiといったログ集約サービスと統合するために構造化ログを必要としている。従来のAstroのログ出力は、色付き表示や罫線文字、複数行エラーフォーマットなど、人間の可読性に特化しており、機械による解析が困難だった。

compose() APIを使えば、人間向けのコンソール出力と機械向けのJSONログを同時に出力できる。

import { defineConfig, logHandlers } from "astro/config";

export default defineConfig({
  logger: logHandlers.compose(
    logHandlers.console(),
    logHandlers.json()
  )
})

この記事のポイント

  • Astro 7.0は.astroコンパイラとMarkdown/MDX処理をRust化し、ビルド時間を15〜61%短縮した
  • Vite 8のRust製バンドラRolldownが標準搭載され、既存の設定をほぼそのまま使える
  • アドバンストルーティングでリクエストパイプラインを完全制御でき、Honoとの統合も可能
  • ルートキャッシングが安定版となり、Netlify/Vercel/CloudflareのCDNキャッシュプロバイダも追加された
  • AIエージェント向けにバックグラウンド開発サーバーとJSONログ出力が自動有効化される
Diviビルダーでカスタムパーマリンクのページが404になる原因と直し方

Diviビルダーでカスタムパーマリンクのページが404になる原因と直し方

Diviビルダーでカスタムパーマリンクを設定した固定ページを編集しようとしたとき、編集画面が404エラーになる現象は、パーマリンク管理プラグインがビルダー専用のクエリパラメータを不正に処理しているために起こる。多くの場合、プラグインの詳細設定で特定のクエリ文字列を除外するだけで解決する。

なぜDiviビルダーがカスタムパーマリンクのページで404エラーを起こすのか

Diviのビジュアルビルダー(フロントエンド編集)は、管理画面から対象ページのURLに「?et_fb=1」といったクエリパラメータを付与し、そのページをiframe内で読み込んで動作する。このとき、パーマリンク管理プラグイン(Permalink Manager Lite など)が設定したカスタムパーマリンクのリダイレクトルールが厳しすぎると、「?et_fb」がついたURLを本来とは別の場所に転送したり、存在しないページとみなして404ステータスを返してしまう。ページ自体は正常に表示されていても、ビルダーという編集専用のアクセスだけがブロックされるかたちになる。

具体的には、パーマリンク管理プラグインの「リダイレクト設定」や「正規化」機能が、付加されたクエリ文字列を除去してしまったり、ビルダー用のパラメータを含むURLをリダイレクト対象から外す設定になっていないことが原因だ。また、一部のキャッシュ設定が影響して、ビルダーがキャッシュ済みの不完全なページを読み込んで404を返すケースもある。

Permalink Manager Lite の設定を調整して404を解消する

カスタムパーマリンクで運用している環境でDiviビルダーが使えなくなったら、まずパーマリンク管理プラグインの詳細設定を見直す。ここでは日本語環境でも多く使われている「Permalink Manager Lite」を例に手順を示すが、他のパーマリンク系プラグインでも同様の考え方で対処できる。

STEP 1 管理画面の「ツール」→「Permalink Manager」→「設定」を開く
STEP 2 「詳細設定」タブをクリックする
STEP 3 「除外するクエリパラメータ」欄に「et_fb」を追加して保存する
設定画面の移動 タブの切り替え 除外指定の追加

上記の「除外するクエリパラメータ」には「et_fb」とだけ入力すればよい。クエリキー名のみをカンマ区切りで列挙する仕様のため、値や「?」を含める必要はない。保存後にDiviビルダーでカスタムパーマリンクのページを開き直し、編集画面が正しく表示されるか確認する。

リダイレクト無効化で管理者の編集を保護する

もう一つの有効な方法は、特定のユーザーに対してリダイレクト機能を一時的に無効化する設定だ。「詳細設定」画面の「リダイレクトを無効化するユーザー」で「管理者」にチェックを入れて保存する。こうすると管理画面からビルダーを開く管理者のリクエストにはリダイレクトルールが適用されず、クエリパラメータがそのまま残るため404が発生しなくなる。ただし、この設定は公開側のパーマリンク動作には影響しない。

デバッグモードで原因を可視化する

設定を変更しても改善しない場合は、「ツール」→「Permalink Manager」→「設定」→「詳細設定」にある「デバッグモード」を有効にしてみる。デバッグモードをオンにすると、ビルダーで404になった際にプラグインがどのURLを解決しようとして失敗したか、詳細なログが記録される。これを見ることで「et_fb」以外に必要な除外パラメータが見つかったり、リダイレクトルールの競合を特定できる。

キャッシュプラグインの影響を切り分ける

キャッシュプラグインの影響を切り分ける

パーマリンク管理プラグインの設定を見直しても直らないときは、サーバーキャッシュやWordPressのキャッシュプラグインの影響を疑う。ビルダー読み込み時の動的URLがキャッシュから誤ったレスポンスを返す場合があるため、以下の手順で一時的にキャッシュを無効化し、症状が消えるか確認する。

  • 使用しているキャッシュプラグイン(WP Super CacheやW3 Total Cacheなど)を一時停止する
  • サーバー側でNginxのfastcgi_cacheやApacheのmod_cacheを使っているなら、管理画面経由でキャッシュをクリアするか、一時的に無効にする
  • ブラウザのキャッシュもクリアしてからビルダーを再読込する

キャッシュを切った状態で編集が成功したなら、キャッシュプラグインの「除外するURLパターン」に「?et_fb」を含む設定を追加する。たとえば、et_fb というクエリ文字列がついたリクエストはキャッシュしないように設定すれば、運用を続けながら編集機能を維持できる。

どうしても直らないときの代替手段

どうしても直らないときの代替手段

上記すべてを試してもビルダーが404を返す場合、根本的にプラグインの仕組みがDiviビルダーと相性が悪い可能性がある。以下の対策を順に検討する。

Before:ビルダー404
カスタムパーマリンク + Permalink Manager Lite → 編集不可
After:編集可能に
クエリパラメータ除外 or プラグイン一時停止でビルダー起動
404エラー状態 編集復旧

パーマリンクプラグインを別のものに切り替える

カスタムパーマリンク機能自体は別のプラグインでも実現できる。「Custom Permalinks」や「WP Permalink」など、Diviとの競合報告が少ないプラグインを試すことで、リダイレクトの挙動を根本から変えられる。ただし、移行時には既存のURL構造を維持できるか事前にテスト環境で確認する必要がある。

ページ編集時だけパーマリンクを一時的にデフォルトに戻す

最終手段として、編集したい固定ページのパーマリンク設定を一時的に「デフォルト(?p=123)」に変更してビルダーで作業し、公開直前にカスタムパーマリンクに戻す方法もある。ただし、編集のたびに手作業が発生するため、恒常的な運用には向かない。

よくある質問

エラーは「このサイトで重大なエラーが発生しました」ではなく「404 Not Found」と表示されるのはなぜか

Diviビルダーはページをiframeで読み込む際に、サーバーに実際のHTTPリクエストを送る。カスタムパーマリンクのルールがリクエストを処理できないと、WordPressのルーティングが失敗し「ページが見つかりません」という404ステータスが返る。これはPHPの致命的エラーではなく、あくまでもURL解決の失敗が原因だ。

特定の固定ページだけ編集できず、他のカスタムパーマリンクページは問題ないのはなぜか

スラッグの重複やリダイレクトルールの複雑さによって、一部のURLだけ誤って別のルールにマッチしてしまうことがある。全ページに同じカスタム構造を割り当てていても、個別に手動で追加したリダイレクト設定が干渉している場合もあるため、プラグインの「重複チェック」や「リダイレクトリスト」を確認する必要がある。

除外するクエリパラメータに「et_fb」を追加しても直らない場合はどうすればよいか

その場合は、ビルダーが使用する可能性のあるすべてのクエリパラメータを確認する。たとえば「et_fb」「et_pb_preview」「et_fb_iframe」「preview」「preview_id」などが考えられる。開発者ツールのネットワークタブでビルダー起動時に送信されるリクエストを調べ、404になっているURLに含まれるパラメータをすべて除外リストに追加する。

キャッシュプラグインを停止しても404が消えない

サーバーレベルのキャッシュ(VarnishやNginx FastCGI)が影響している可能性がある。レンタルサーバーの管理パネルからキャッシュを手動でクリアするか、サーバー会社のサポートに一時的なキャッシュ停止を依頼して切り分ける。WordPressのキャッシュプラグインだけでは制御できない層があるためだ。

この記事のポイント

  • パーマリンク管理プラグインの除外設定に「et_fb」を追加すれば大半のケースで解決する
  • 管理者向けのリダイレクト無効化も有効な回避策になる
  • キャッシュプラグインやサーバーキャッシュが404を悪化させることがあるため、一時停止して切り分ける
  • デバッグモードで詳細なログを確認すれば、除外すべき追加パラメータを特定できる
  • 根本的に相性が悪い場合は、パーマリンクプラグインの変更も選択肢に入る
CSSスクロール駆動アニメーションで逆方向スクロールを実現

CSSスクロール駆動アニメーションで逆方向スクロールを実現

スクロールに応じてアイテムが上下逆方向に動くレイアウトを実現する手法がある。CSS-Tricksの著者が紹介したこのテクニックは、CSSの「スクロール駆動アニメーション」と疑似要素によるマスク効果を組み合わせたものだ。通常のアニメーションと異なり、ユーザーがスクロールした量だけアニメーションが進行するため、インタラクティブな表現が可能になる。本記事ではその仕組みと実装手順を詳しく解説する。

具体的なコードを見ていこう。元記事では3つのカラムがあり、左右のカラムはスクロールに応じて上方向へ、中央のカラムは下方向へ移動する。コンテナの上下端ではアイテムがふわりと消えるフェード効果がかかる。この動きはCSSの animation-timeline プロパティと view() 関数で制御される。

スクロール駆動アニメーションの基本概念

スクロール駆動アニメーションの基本概念

スクロール駆動アニメーション(Scroll-Driven Animations)とは、アニメーションの進行をスクロール位置に連動させるCSSの新機能である。従来のCSSアニメーションは時間ベースで動いていたが、この機能を使えば「要素が画面のどこにあるか」や「スクロール量がどれだけ進んだか」を基準にアニメーションを再生できる。

これを実現するのが animation-timeline プロパティだ。ここには scroll() 関数または view() 関数を指定する。scroll() は親要素やルートのスクロール位置を追跡し、view() は要素自身がスクロールポート(スクロール可能な表示領域)に出入りする過程を追跡する。今回の逆方向スクロールでは、各カラム内のアイテムがコンテナ領域に入ったり出たりする動きが肝になるため、view() が採用された。

view() 関数の仕組み

view() 関数は、アニメーション対象の要素がスクロールポートのどの範囲にあるかを0%から100%の進捗で返す。例えば、要素がスクロールポートの下端にさしかかった瞬間が0%、完全に反対側へ出切った瞬間が100%だ。この進捗をアニメーションのタイムラインにマッピングすることで、スクロールに同期した動きを作れる。

CSS-Tricksの著者は、この関数に「entry 0% cover 100%」というインセットを設定している。これは、要素がスクロールポートに入り始めた瞬間(entry)の0%から、完全に通り抜けて隠れきった瞬間(cover)の100%までをアニメーションの範囲とする指定だ。この設定により、各カラムのアイテムが表示領域に姿を現し、消えるまでの全行程をアニメーションでカバーできる。

Before:要素がスクロールポート外
アイテム
After:スクロールで要素がポート内に進入、フェードしながら通過
アイテム

このデモは、要素がスクロールポートに出入りする際のマスク効果を静的に表現している。実際のブラウザでは、スクロール量に応じて要素の位置が連続的に変化し、上下のグラデーション部分に重なると自然に溶け込むように見える。

animation-range による範囲の精密制御

animation-range プロパティは、タイムラインのどの区間を使ってアニメーションを再生するかを決める。デフォルトでは「entry 0% exit 100%」だが、CSS-Tricksの例では「entry 0% cover 100%」としている。これは entry が「要素がスクロールポートに入り始める瞬間」、cover が「要素がポートを完全に覆い隠した瞬間(つまり反対側へ出切った瞬間)」の2点を基準にする記法だ。

この指定により、アイテムが画面に現れた瞬間から消える最後までアニメーションが継続する。逆に言えば、画面外に完全に隠れている間はアニメーションが停止しているのと同じ状態になる。結果として、ユーザーがスクロールしている間だけアイテムがスムーズに動き続けるインタラクションが実現する。

HTMLのシンプルな構造

HTMLのシンプルな構造

CSS-Tricksの記事で示されているHTMLは非常に簡素だ。複雑なJavaScriptや追加のラッパーは不要で、大きく分けて3階層の要素があればよい。

<div class="opposing-columns">
  <div class="opposing-column">
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
  </div>
  <div class="opposing-column">
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
  </div>
  <div class="opposing-column">
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
    <div class="opposing-item">...</div>
  </div>
</div>
コンテナ
opposing-columns
子要素として3つのカラムを収容
Flexコンテナ マスク生成
各カラム
opposing-column
内部でさらにグリッドレイアウトを形成
Gridコンテナ アニメーション適用
アイテム
opposing-item
実際に上下移動する要素

このシンプルな構造がポイントだ。CSS側でスクロール駆動アニメーションを定義する際、各カラム(.opposing-column)ごとに異なるアニメーションを適用し、その中に含まれるアイテムが一括して動く仕組みになっている。

CSSによるマスク効果の実装

CSSによるマスク効果の実装

アイテムがコンテナの上下端でふわっと消える演出は、疑似要素とグラデーションによるマスクで作られている。透明度や opacity を直接操作するのではなく、背景色と同じ色のグラデーションを重ねることで、コンテンツが自然に隠れるように見せているのだ。

疑似要素でマスクを生成する

親コンテナ .opposing-columnsposition: relative を設定したうえで、::before::after 疑似要素を絶対配置している。これらの疑似要素はコンテナの上下にそれぞれ配置され、幅はコンテナ全体、高さはCSS変数 --opposing-mask の3倍に設定されている。

@media screen and (width >= 50rem) {
  .opposing-columns {
    position: relative;
    margin-block: var(--opposing-mask, 3rem);
  }

  .opposing-columns::before,
  .opposing-columns::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    block-size: calc(var(--opposing-mask) * 3);
    pointer-events: none;
    z-index: 1;
  }
}
疑似要素 before
疑似要素 after
カラムエリア
アイテムが上下から出入り

疑似要素には pointer-events: none が指定されており、クリックやホバーの邪魔をしない。これはユーザビリティを損なわないための重要な配慮だ。

グラデーションで自然なフェードを生み出す

次に、これらの疑似要素に線形グラデーションを適用する。上側の ::before には to bottom(上から下)方向のグラデーションを設定し、始点をドキュメントの背景色 --opposing-bg、終点を透明にする。下側の ::after はこれを逆にして、to top(下から上)方向のグラデーションを設定する。

.opposing-columns::before {
  background-image: linear-gradient(
    to bottom,
    var(--opposing-bg) var(--opposing-mask),
    transparent
  );
  inset-block-start: calc(var(--opposing-mask) * -1);
}

.opposing-columns::after {
  background-image: linear-gradient(
    to top,
    var(--opposing-bg) var(--opposing-mask),
    transparent
  );
  inset-block-end: calc(var(--opposing-mask) * -1);
}
マスクの役割イメージ(縦方向)
上部マスク(before)
アイテムがクリアに表示
下部マスク(after)

これにより、カラム内のアイテムがコンテナの上下端に近づくと、グラデーション部分に重なって自然に消えていくように見える。背景色とマスクの色が同一であるため、アイテムが溶け込むようなスムーズなフェードが実現する。

キーフレームアニメーションの設計

キーフレームアニメーションの設計

マスクの準備が整ったら、実際にアイテムを上下に動かすアニメーションを定義する。CSS-Tricksの著者は3つの異なるキーフレームを用意し、各カラムに割り当てている。

3種類の動きをキーフレームで定義

アニメーションは transform: translateY() による垂直移動で構成される。1つ目の scroll1 はアイテムを上方向に移動させ、2つ目の scroll2 はその逆方向(下方向)に動かす。3つ目の scroll3 はややオフセットを持たせた上方向の動きで、カラム間のタイミングにわずかなズレを生み出している。

@keyframes scroll1 {
  from { transform: translateY(var(--opposing-mask)); }
  to   { transform: translateY(calc(var(--opposing-mask) * -1)); }
}

@keyframes scroll2 {
  from { transform: translateY(calc(var(--opposing-mask) * -1)); }
  to   { transform: translateY(var(--opposing-mask)); }
}

@keyframes scroll3 {
  from { transform: translateY(calc(var(--opposing-mask) * .66)); }
  to   { transform: translateY(calc(var(--opposing-mask) * -.33)); }
}
scroll1 上方向へ移動(from 下 → to 上)
scroll2 下方向へ移動(from 上 → to 下)
scroll3 オフセット付き上方向(66%開始→33%終了)

このオフセットの考え方は応用が利く。例えば同じ方向に動く2つのカラムでも、開始位置を微妙にずらすだけで視覚的なリズムが生まれ、単調さを回避できる。

カラムごとに異なるアニメーションをバインド

キーフレームを定義したら、各カラムにアニメーション名を割り当てる。nth-of-type 疑似クラスを使い、1番目のカラムには scroll1、2番目には scroll2、3番目には scroll3 を適用する。これにより、カラムの位置に応じて移動方向が自動的に決まる。

.opposing-column:nth-of-type(1) { animation-name: var(--animation-1); }
.opposing-column:nth-of-type(2) { animation-name: var(--animation-2); }
.opposing-column:nth-of-type(3) { animation-name: var(--animation-3); }

さらに、これらのアニメーションは animation-timeline: view()animation-range: entry 0% cover 100%、そして animation-timing-function: linear がセットで指定される。線形のタイミング関数を選ぶことで、スクロール速度に応じてアイテムが等速で動き、自然な同期感が得られる。

アクセシビリティとブラウザ対応

アクセシビリティとブラウザ対応

実装にあたっては、モーションに敏感なユーザーへの配慮と、ブラウザ間の互換性を考慮する必要がある。CSS-Tricksの元記事でもこの点に言及しており、適切なフォールバックを組み込んでいる。

prefers-reduced-motion への対応

OSやブラウザの設定で「視差効果を減らす」を有効にしているユーザー向けに、メディアクエリ prefers-reduced-motion: reduce を用いてアニメーションを無効化する。このクエリが一致した場合、アニメーションを unset で打ち消し、さらに疑似要素のマスクも削除する。マスクだけが残ると、動かないアイテムが不自然に隠れてしまうからだ。

@media (prefers-reduced-motion: reduce) {
  .opposing-column {
    animation: unset;
  }
  .opposing-column::before,
  .opposing-column::after {
    content: unset;
  }
}

これにより、動きを減らしたいユーザーには静的なレイアウトが提供され、意図しないストレスを回避できる。

@supports を使った段階的な実装

スクロール駆動アニメーションは、2026年6月時点でChromeとSafariがサポートしているが、Firefoxは未対応だ。そのため、@supports (animation-timeline: view()) を用いて、機能が使えるブラウザでのみアニメーションを有効化するのが安全だ。サポートされない環境では、通常のスクロールと同様の静的な表示になるよう設計しておけば、すべてのユーザーに破綻のない体験を届けられる。

@supports (animation-timeline: view()) {
  /* スクロール駆動アニメーションのスタイル */
}
対応状況の概念(2026年6月時点)
Chrome 対応 Safari 対応 Firefox 未対応
@supportsで振り分けることで、未対応ブラウザには静的なフォールバックが適用される

この手法はプログレッシブエンハンスメントの好例で、新しいCSS機能を安全に導入したい現場でも参考になるだろう。

独自の視点:逆方向スクロールの応用可能性

独自の視点:逆方向スクロールの応用可能性

ここまで見てきたテクニックは、単なる逆方向スクロールの演出にとどまらない。CSSのスクロール駆動アニメーションは、タイムラインを自在に操作できるため、さまざまなインタラクティブ表現の土台となる。

タイミングのオフセットを使ったリズム演出

元記事の scroll3 のように、開始位置や終了位置をパーセンテージでずらすことで、カラム間の動きにリズムを生み出せる。たとえば、5カラムのレイアウトでそれぞれの移動量を微調整すれば、波のようなうねりを表現することも可能だ。マスクの高さやアニメーションのインセットをCSS変数で管理しておけば、デザインの微調整も容易になる。

単調な例(Bad)
全カラムが同じタイミングで動く
カラムA カラムB カラムC
オフセット付き(Good)
カラムごとに開始位置をずらしてリズムを生む
カラムA 0% カラムB 20%遅延 カラムC 40%遅延

このようなオフセット設計は、プロモーションサイトやポートフォリオのビジュアルリッチなセクションで特に効果を発揮するだろう。

パララックス効果との自然な組み合わせ

従来のパララックス(視差効果)はJavaScriptで実装されることが多かったが、スクロール駆動アニメーションを使えば、CSSだけで多層的な視差を表現できる。背景画像や装飾要素に別の animation-timeline を割り当て、移動速度を変えれば、奥行きのあるスクロール体験をJavaScriptに頼らずに構築できる。

例えば、背景の大きな画像にはゆっくりした上方向のアニメーションを、前景のテキストにはやや速い動きを設定するといった組み合わせだ。マスク効果を応用すれば、画面外への自然な消え方も統一感を持って演出できる。

カルーセルやタイムライン表現への展開

逆方向スクロールの考え方は、横方向のカルーセルやタイムライン表示にも転用できる。view() 関数の軸指定(blockinline)を切り替えれば、水平スクロールにも対応可能だ。また、scroll() 関数と組み合わせれば、ページ全体のスクロール量に応じてインジケーターを進める、といった使い方もできる。

スクロール駆動アニメーションの応用先(例)
パララックス背景 水平カルーセル タイムライン スクロールインジケーター

CSS-Tricksの元記事は比較的シンプルな例だが、この基盤さえ理解すれば、より複雑なレイアウトやストーリーテリング演出にも発展させられる。

この記事のポイント

  • スクロール駆動アニメーションは animation-timeline: view() で実装し、スクロールに同期した動きを簡単に作れる
  • 疑似要素と背景色ベースのグラデーションを組み合わせると、自然なフェード効果を実現できる
  • 動きのオフセットや逆方向設定によって、単調でないリズミカルな演出が可能になる
  • @supportsprefers-reduced-motion で、アクセシビリティとブラウザ互換性を両立させる
  • 今回のテクニックはパララックス、水平カルーセル、タイムラインなど多彩な表現に展開できる
プラグイン更新後にログイン不可「ユーザー名またはパスワードが間違っています」と表示される原因と直し方

プラグイン更新後にログイン不可「ユーザー名またはパスワードが間違っています」と表示される原因と直し方

プラグインの更新後、正しいユーザー名とパスワードを入力しているにもかかわらずログインできず「ユーザー名またはパスワードが間違っています」というエラーが表示されるなら、その原因は特定のプラグインが認証フローに干渉したことによる競合だ。特にログインフォームをカスタマイズするプラグインと、追加のセキュリティ認証(Cloudflare Turnstileなど)を組み合わせている場合に発生しやすい。

なぜ正しいパスワードなのに「間違っています」と表示されるのか

なぜ正しいパスワードなのに「間違っています」と表示されるのか

WordPressは通常、ログイン認証を「wp-login.php」を通じて処理している。ここにプラグインが独自のログインフォームを追加したり、認証前にCAPTCHAや追加認証を挟むと、データの送信順序や検証の流れが変わる。プラグインのバージョンアップでこの処理順序が微妙に変わった結果、正しい認証情報がバックエンドの判定に渡る前に「誤り」と判定されるケースが起きる。

典型的なパターンとして、会員制サイト用のプラグイン(Ultimate Memberなど)が生成する独自ログインページと、追加のボット対策機能(Cloudflare TurnstileやreCAPTCHA)が衝突する問題が挙げられる。どちらか一方が先にフォームの値を検証し、もう一方に正しい情報を渡せなくなることが原因だ。

■ エラー発生時の処理の流れ(競合)
ログインフォーム セキュリティ認証(Turnstile) WordPress認証
認証トークンの不一致や情報の欠落が発生 → WordPressが「ユーザー名またはパスワードが間違っています」と誤判定する

まず試す緊急回避策 管理画面に入れない場合の対処

まず試す緊急回避策 管理画面に入れない場合の対処

ログインできない状態では管理画面からプラグインを停止できない。次のいずれかの方法でプラグインを一時的に無効化し、管理画面に再アクセスできるようにする。

FTPやファイルマネージャーでプラグインフォルダの名前を変更する

レンタルサーバーのファイルマネージャーやFTPソフトでサイトのファイルにアクセスし、「/wp-content/plugins/」ディレクトリを開く。問題を起こしているプラグインのフォルダ名を一時的に「_(アンダースコア)」を付けるなどして変更する。WordPressは存在しないプラグインディレクトリを無効化するため、余分な認証処理が外れて本来のログインフローが復活する。

具体的な対象は、直近で更新したプラグインか、ログインフォームをカスタマイズしているプラグインだ。Ultimate Memberのような会員制プラグインや、Cloudflare Turnstileを追加しているプラグインが該当する。

wp-config.phpでプラグインを一括無効化する

FTPでWordPressのルートディレクトリにある「wp-config.php」をダウンロードし、次の一行を「/* 編集が必要なのはここまでです ! */」の直前に追加する。

define('DISABLE_PLUGINS', true);

この状態でファイルを上書きアップロードすると、すべてのプラグインが一時的に無効化される。管理画面にログインできたらこの行を削除し、原因のプラグインだけを停止してから他のプラグインを再有効化する。ただし、この定数は非公式の回避策で、すべての環境で動作するとは限らない点に注意する。

原因となったプラグインの特定と恒久対応

原因となったプラグインの特定と恒久対応

管理画面にログインできたら、プラグイン一覧画面で「直近更新されたプラグイン」を順に停止し、問題が再現するか確認する。特に次の組み合わせに心当たりがあれば、真っ先に疑うべきだ。

  • 独自のログインフォームを提供するプラグイン(Ultimate Memberなど)
  • Cloudflare TurnstileやreCAPTCHAなどの認証機能をログイン画面に追加するプラグイン
STEP 1 プラグイン一覧で更新日時を確認し、直近更新されたプラグインを特定する
STEP 2 そのプラグインの追加認証機能(Turnstileなど)を設定画面で一時的に「無効」にする
STEP 3 シークレットウィンドウでログイン画面を開き、正しくログインできるかテストする
STEP 4 問題が解決したら、プラグインを旧バージョンに戻すか、開発元に不具合を報告する

旧バージョンに戻す方法

プラグインの以前のバージョンは、WordPress公式プラグインディレクトリの「以前のバージョン」セクションからダウンロードできる。プラグインページの下部にある「詳細を見る」→「開発」→「以前のバージョン」の順に進むと、過去のすべての安定版がzipで入手可能だ。管理画面のプラグイン新規追加から手動でアップロードし直すか、FTPで「/wp-content/plugins/」に解凍して上書きすれば戻せる。

Cloudflare Turnstileをそのまま使いたい場合の設定見直し

TurnstileのWidget Modeを「Managed」から「Non-interactive」に変更するか、ログインページだけ設定を除外する方法を試すと競合が緩和されることがある。Cloudflareのダッシュボード側で該当サイトの「Security → Bots → Turnstile」から、Fail-open動作(認証失敗時にアクセスを通す)を有効にするのも有効な回避策だ。

根本原因を理解して今後の更新に備える

根本原因を理解して今後の更新に備える

この問題の本質は、WordPressの認証フック(authenticateフィルター)に対して複数のプラグインが非標準的な順序で割り込んだことにある。WordPressのコア認証は、ユーザー名とパスワードが一致したらWP_Userオブジェクトを返す。しかし追加認証を挟むプラグインは、認証が成功しても「null」を返したり、エラーオブジェクト(WP_Error)に差し替えたりする。バージョンアップでこのフィルターの優先度(priority)が変わると、突然認証が通らなくなるというわけだ。

将来的に同様のトラブルを避けるには、本番環境の更新前にステージング環境で動作確認することが最も確実な対策になる。また、会員制プラグインとセキュリティ認証プラグインの両方を使用している場合は、片方のログイン機能をオフにしてWordPress標準のログインページに一本化するのも安定性を高める選択肢だ。

よくある質問

Ultimate Memberのログインフォームだけエラーになるのはなぜか

Ultimate MemberはWordPress標準の認証処理を大きくカスタマイズし、独自の認証フックを追加している。ここにCloudflare Turnstileのような外部検証が割り込むと、UM側で生成したnonce(ワンタイムトークン)やセッション情報が検証前に消費されたり、書き換えられてしまう。UMはバリデーションが1つでも失敗すると「認証情報が間違っている」と一般化して表示する設計のため、実際のパスワードは合っていてもエラーになる。

プラグインを旧バージョンに戻したがサイトが脆弱にならないか

旧バージョンに戻すことは一時的な対処であり、修正が適用された最新版に更新できるまでの猶予と考えるべきだ。緊急回避の間は、WAF(Webアプリケーションファイアウォール)のルールを厳しくする、ログイン試行回数の制限をかける、IP制限を追加するなど、他の手段で防御を補強しておく。該当プラグインのサポートフォーラムで同様の報告がないか確認し、解決パッチを待つか、開発元に直接報告するのが安全な進め方だ。

Cloudflare Turnstileを完全に外す以外の選択肢はあるか

Cloudflare側の設定で「アクション」を「管理モード」から「監視モード」に変更し、認証を可視化せず裏側でリスク評価だけさせる手がある。また、一部のプラグインでは特定のページ(wp-login.phpなど)だけ検証をスキップするフックが用意されている場合がある。プラグインのドキュメントやフックリファレンスに「bypass turnstile on specific page」の情報がないか探してみるとよい。

管理画面にすら入れない場合、データベースから直接プラグインを無効化できるか

可能だ。phpMyAdminなどでWordPressのデータベースにアクセスし、「wp_options」テーブルの「active_plugins」レコードを編集する。このレコードには有効化されているプラグインの一覧がシリアライズされた配列で保存されている。該当プラグインのパスを削除して保存すれば、そのプラグインだけが無効化される。ただしシリアライズされたデータの文字数カウントを修正する必要があるため、FTPでのフォルダ名変更のほうが手軽で安全だ。

この記事のポイント

  • 正しいパスワードでログインエラーになるのは、認証フックに割り込むプラグインの競合が原因
  • FTPで問題のプラグインフォルダをリネームするか、wp-config.phpで全プラグインを一時停止して管理画面に入る
  • Cloudflare TurnstileやreCAPTCHAの設定をオフにするか、旧バージョンへのダウングレードで即座に解決する
  • 恒久対応は、開発元への不具合報告と、ステージング環境での更新前検証の徹底
  • 同種のプラグインを併用する場合は、WordPress標準ログインページへの統一も検討する
EC向けAIフライホイール構築、4つの価値レバーと実践法

EC向けAIフライホイール構築、4つの価値レバーと実践法

EC事業におけるAI活用は、単純なタスクの自動化から、複数の施策が連鎖的に成果を生み出す仕組み作りへと移行しつつある。マッキンゼー・アンド・カンパニーが2026年6月に公開したレポート「Europe’s new ecommerce agenda How AI is resetting growth and competition」では、AIがもたらす価値は断片的な実験ではなく統合にあると指摘されている。

成功するEC事業者は、商品のパーソナライズ、需要予測、在庫管理、価格設定といった複数の意思決定をAIでつなぎ合わせ、全体として加速度的に回転する「フライホイール」を構築している。このフライホイールは、各施策が互いに強化し合い、一度回り始めると追加のリソースを大きく投じなくても成果が積み上がっていく。

この記事では、マッキンゼーが示した「4つの価値レバー」を軸に、大企業だけでなくデータや人的リソースが限られる中小規模EC事業者でも実践できる小さなAIフライホイールの始め方を、具体例とともに解説する。

AIフライホイールの基本概念

AIフライホイールの基本概念

フライホイールが回る仕組み

AIフライホイールとは、あるプロセスが次のプロセスを改善し、その改善が再び最初のプロセスを後押しする、自己強化型の循環システムのことだ。たとえば、AIによるパーソナライズで顧客エンゲージメントが高まると、より正確な需要シグナルが得られる。そのシグナルを使って価格や在庫の判断を最適化すれば、再びエンゲージメントが向上し、さらに多くのデータが蓄積される。

このループを1回転させるごとに、データの質と意思決定の精度が上がり、フライホイールはより少ないエネルギーで回り続ける。一度きりのプロジェクトではなく、持続的な成長エンジンとして機能する点が最大の特徴だ。

単体タスクの自動化との違い

AIフライホイールは、単一の作業をAIに任せる「自動化」とは根本的に異なる。商品説明文をAIで生成すれば時間は短縮できるが、それだけではビジネス全体の流れは変わらない。一方、フライホイール思考では、顧客からの問い合わせ内容をAIで分析し、商品ページの改善に活かし、コンバージョン率の変化を追跡し、その結果を次の仕入れや価格戦略に反映させる。こうした相互連鎖によって、初めて収益構造が強化される。

従来の断片的なAI導入(Before)
チャットボットだけ導入
商品説明文を自動生成
需要予測を単体で実施
※各施策が孤立し、データが循環しない
フライホイール型のAI活用(After)
顧客フィードバックをAI分析
商品ページの改善とテスト
コンバージョンと需要シグナルが向上
価格や在庫の最適化に反映
↻ 次のサイクルへ
※データと意思決定が連鎖し、ループが加速する

この概念図では、断片化されたAI活用と、連鎖的に回るフライホイールの違いを視覚化している。単体の導入では部分最適にとどまるが、相互に強化し合うループを作ることで、事業全体の底上げが可能になる。

成長を加速する4つの価値レバー

成長を加速する4つの価値レバー

相互に強化し合う4つの要素

マッキンゼーのレポートでは、ECにおけるAIフライホイールを構成する4つの「価値レバー」として、成長、生産性、バリューチェーン効率、収益性が挙げられている。いずれも独立した施策ではなく、意図的につなぎ合わせることでレバレッジが効く。

成長は、商品発見の最適化やレコメンデーション、メールセグメンテーション、広告クリエイティブの自動生成などを通じて、適切な購入者に適切な商品を届ける活動を指す。AIが顧客行動を深く理解し、一人ひとりに合った購買体験を提供することで、売上の上昇に直結する。

生産性は、カスタマーサポートやコンテンツ制作、販売管理、レポート作成といった反復作業をAIで削減する領域だ。定型業務から人手を解放し、戦略的な思考が求められる高付加価値業務に人材を集中させられる。

バリューチェーン効率は、需要予測と在庫管理、フルフィルメント、返品処理をAIで連携させるものだ。何が売れるか、どこに在庫があるか、いつ届くかをリアルタイムに把握し、コストと在庫リスクを最小化する。

収益性は、価格設定やプロモーション、バンドル販売、値下げ判断をデータ駆動で行う領域である。AIは利益率を損なう過度な値引きや無駄なキャンペーンを可視化し、マージンを最大化する行動を提案する。

成長

商品発見、レコメンド、広告クリエイティブの最適化で適切な顧客にリーチ

↓ 相互にデータを供給
生産性

反復作業の削減と人員の高付加価値業務へのシフト

バリューチェーン効率

需要・在庫・配送・返品を統合しコストを最小化

収益性

価格・プロモーション・値下げ判断のデータ駆動化で利益率を向上

↻ このループが回るほど意思決定の精度が上がる
成長  生産性  効率  収益性

これら4つのレバーは、相互にデータを供給し合うことで単体の数倍の効果を発揮する。たとえば、成長施策で得たエンゲージメントデータが在庫効率を改善し、その結果生まれた余剰在庫をデータに基づく値下げ判断で処理しながら収益性を守る、といった連携が可能だ。

中小規模ECが実践できる小さなフライホイール

中小規模ECが実践できる小さなフライホイール

顧客フィードバック分析から商品ページ改善へ

大企業のように整備されたデータ基盤や高度なシステムがなくても、AIフライホイールは始められる。中小規模EC事業者であっても、問い合わせメールやチャット履歴、レビュー、返品理由といった顧客の声は確実に存在している。これらをAIで分析し、たとえば「サイズ感が合わない」「同梱物がわかりにくい」「配送目安が不明瞭」といった共通の課題を抽出することが、最初の一手になる。

次に、得られたインサイトを商品ページの改善に反映する。サイズガイドの追加や比較表の設置、よくある質問の充実、利用シーンを想起させる商品写真の差し替えなど、具体的な対応を取るのが有効だ。これらの変更は、無料または低コストのAIツールで十分に実施できる。

改善が次のサイクルを生む

商品ページの改修後は、コンバージョン率や返品率、サポートへの問い合わせ件数といった指標を追跡する。ここでもAIを活用すれば、変更の効果を自動で検知し、仮説の精度を高めていくことが可能だ。たとえば「返品理由の上位にあったサイズ感の問題が解消され、返品率が15パーセント低下した」といった成果が得られれば、次の購買データもクリーンになる。

こうした小さなサイクルを繰り返すことで、顧客の声が商品体験を改善し、改善がより良いデータを生み、そのデータがさらに精度の高い意思決定を支えるループが出来上がる。規模は小さくとも、自己強化のメカニズムは大企業のそれと同じだ。

STEP 1 顧客の声(メール・チャット・レビュー・返品理由)をAIで分析
STEP 2 共通課題を特定し、商品ページやFAQを改善
STEP 3 コンバージョン率や返品率の変化をAIで追跡
STEP 4 改善結果が新たなデータとなり、次の分析の精度が上がる
↻ サイクルを繰り返すほど成果が積み上がる

この小さなフライホイールは、初期投資を抑えながら着実に成果を出せる。顧客フィードバックはすでに手元にある資産であり、AIを分析エンジンとして活用するだけで、商品改善と売上向上のエンジンが動き始める。

意思決定の連鎖がもたらすもの

意思決定の連鎖がもたらすもの

部門を横断したAI活用

AIフライホイールの本質は、カスタマーサービスと商品コンテンツ、サイト内検索とマーチャンダイジング、在庫管理とプロモーションといった、これまで別々に行われてきた意思決定を一本の線でつなぐことにある。AIが仲介役となり、各部門から得られるデータを相互に変換しながら、最適なアクションを導き出す。

たとえば、顧客からの問い合わせに使われる自然言語の傾向をAIが学習すれば、それはサイト内検索のレコメンド精度向上にも活かせる。また、返品理由の分析結果をプロモーション担当に共有すれば、値引きすべき商品や強化すべき訴求ポイントが明確になる。AIがデータの共通言語となることで、組織全体の意思決定が同期し始める。

マネジメント視点の重要性

中小EC事業者が真にAIで競争優位を築けるかどうかは、最新モデルへのアクセスよりも、経営的な視点の差で決まる。AIを単なるツールとして導入するのではなく、業務プロセス全体を俯瞰し、データが流れる経路を設計し、測定と改善を繰り返す管理のしくみを構築することが求められる。

これは技術の話ではなく、経営戦略の話だ。顧客の声を商品に反映し、その成果を在庫や価格に転嫁し、得られた利益を再び顧客体験に投資する。この連鎖を回す主体は、AIではなく事業者自身である。AIはその回転を支えるエンジンに過ぎない。

この記事のポイント

  • AIフライホイールは、部分的な自動化ではなく、複数の施策が連鎖して加速する自己強化型のシステムである
  • マッキンゼーが示す成長、生産性、バリューチェーン効率、収益性の4つのレバーを組み合わせることで、レバレッジが最大化される
  • 中小EC事業者は、すでに保有する顧客フィードバックをAIで分析し、商品ページ改善につなげる小さなサイクルから始められる
  • AIの真価は、部門を横断した意思決定の同期と、経営全体をデータ駆動で回すマネジメントの仕組みにある
PHP Parse Error unexpected クエスチョンでWordPressが真っ白になる原因と直し方

PHP Parse Error unexpected クエスチョンでWordPressが真っ白になる原因と直し方

「PHP Parse error: syntax error, unexpected ‘?’」が error_log に記録され、WordPress の管理画面を含むサイト全体が真っ白になる症状は、実行環境の PHP バージョンが古すぎて、WordPress コアファイルが記述する構文を解釈できないことが原因だ。とくに wp-includes/compat-utf8.php の 47 行目でエラーになるケースでは、PHP 5.x 系で動作している可能性が高い。サーバーの PHP を 7.4 以上(WordPress 7.0 の動作要件には 8.0 以上が推奨)に切り替えれば、このエラーは即座に解消する。

なぜ compat-utf8.php で unexpected ‘?’ が発生するのか

なぜ compat-utf8.php で unexpected ‘?’ が発生するのか

WordPress のコアファイル compat-utf8.php は、マルチバイト文字列を安全に扱うための互換関数群を収めている。中では null 合体演算子(??)やシンプルな三項演算子が使われる場面があり、これらは PHP 7.0 以降で導入された構文だ。もしサーバーが PHP 5.6 以前のバージョンで動作していると、「?’」の部分で構文エラーが発生し「unexpected ‘?’」というメッセージを吐く。つまり PHP バージョン不足が根本原因になる。

エラーの「expecting variable (T_VARIABLE)」は、処理系が疑問符を見て、本来そこに変数が来るはずの三項演算子の前半部分と誤解したことを示す。古い PHP は「??」を認識できずに文法的に未知のトークンとしてパースエラーを起こす。WordPress 7.0 が標準で要求する PHP バージョンはさらに高く、8.0 以降を推奨するケースも多い。

Before PHP 5.6 で実行
compat-utf8.php で「unexpected ‘?’」
サイト全体が真っ白
After PHP 8.0 に切り替え
エラー消滅、サイトが正常に表示
エラー状態  復旧後

上図のように PHP バージョンが低いとコアファイルの構文エラーで画面が真っ白になり、適切なバージョンにすると何も修正しなくてもその場で直る。

PHP バージョンを確認してサーバーで変更する手順

PHP バージョンを確認してサーバーで変更する手順

最初にサーバーが現在どの PHP バージョンで動いているかを調べ、続いて管理画面からバージョンを切り替える。操作性はレンタルサーバーによって異なるが、多くの場合 cPanel か独自コントロールパネルに PHP セレクターが用意されている。

STEP 1 phpinfo() ファイルで現在の PHP バージョンを調べる
STEP 2 サーバー管理画面の「PHP バージョン選択」で PHP 7.4 以上に切り替える
STEP 3 サイトを再読み込みしてエラーが消えたことを確認する

phpinfo() で現在の PHP バージョンを調べる

サーバーの公開ディレクトリに info.php などのファイルを作り、内容を <?php phpinfo(); ?> にしてブラウザで開く。表示されるページの最上部に「PHP Version」として現在のマイナーバージョンまで確認できる。この値が 5.6 や 7.0 であれば、まさにこの構文エラーを引き起こす原因になっている。

コントロールパネルで PHP バージョンを変更する

cPanel の場合は「Select PHP Version」または「マルチPHP マネージャー」といった項目からドロップダウンで選択し、その場で切り替えが可能だ。PHP 7.4 や 8.0 が用意されていないときは、ホスティング会社のサポートに「PHP のバージョンアップグレードをお願いします」と連絡して対応を依頼する。

WordPress が推奨する動作環境は年々上がっている。WordPress 7.0 であれば PHP 8.0 以降を選択するほうが安全で、プラグインの互換性も考慮してなるべく新しい安定バージョン(8.1 や 8.2)を選ぶとよい。

変更後にサイトが復旧したかどうか確認する

PHP バージョンを切り替えたら、キャッシュが残らないようシークレットウィンドウで管理画面とトップページを開く。真っ白だった画面が正常に表示されれば解決だ。もし引き続きエラーが出る場合は、次節のチェックポイントを試す。

PHP をアップグレードしても直らないときの確認ポイント

PHP をアップグレードしても直らないときの確認ポイント

PHP バージョンが適切でも compat-utf8.php で同じエラーが出るなら、コアファイルの破損や、別の場所から読み込まれた古い互換コードが原因の可能性が残る。

コアファイルを再アップロードして整合性を確かめる

wp-admin と wp-includes ディレクトリ、およびルートのファイルを公式アーカイブからダウンロードし、FTP で上書きする。このとき wp-content は触らない。アップロード後もエラーが出るなら、WP-CLI が使える環境では「wp core verify-checksums」コマンドでファイルの改ざんや破損を検出できる。

wp-content 内のカスタムコードを調査する

まれに mu-plugins(Must Use プラグイン)やテーマの functions.php に記述された互換用のオーバーライドが、古い PHP 構文を含んでいるケースがある。wp-content/mu-plugins を一時的に空にし、子テーマを標準テーマに切り替えてアクセスしてみる。これでエラーが消えたら、該当ファイル内の記述を新しい書き方に書き換える必要がある。

サーバーの .htaccess や php.ini を確認する

特定のディレクトリだけ古い PHP ハンドラが割り当てられている場合、.htaccess に AddHandler や SetHandler で別バージョンが指定されていることがある。推測されるハンドラ名があればコメントアウトして様子を見る。また、php.ini に意図しない設定でバージョン互換モードが指定されていないかも確認する。

よくある質問

エラーメッセージの unexpected ‘?’ と expecting variable は何を意味しているのか

PHP がソースコードを解析する際に、予期しない「?」を見つけて構文エラーを起こしたという意味だ。古い PHP では null 合体演算子(??)が文法として認識されず、単独の疑問符として解釈され「ここには変数が来るべきだ」と報告される。PHP 5.6 以下でしか発生しない典型的なエラーパターンである。

WordPress 7.0 にアップグレードしたらこのエラーが出るのはなぜか

WordPress 7.0 のコアが新たに PHP 7.4 や 8.0 の構文を使い始めたためだ。以前のバージョンでは問題なく動いていても、最新のコアに置き換えた途端に PHP のバージョン要件が上がり、サーバー側が追いついていないと構文エラーが発生する。

レンタルサーバーで PHP バージョンが変更できない場合の対処法は

低スペックの格安プランや古い共用サーバーでは PHP セレクターが提供されていないこともある。その場合はホスティング会社のサポートへ「PHP のバージョンを 7.4 以上に変更してほしい」と申請する。対応してもらえなければ、別のサーバーへの移転も検討する必要がある。

compat-utf8.php 以外のファイルで同じ構文エラーが出た場合も同じ対処でいいのか

はい。ファイル名が異なっていても、unexpected ‘?’ という構文エラーは PHP バージョン不足が原因である可能性が極めて高い。ただ、プラグインやテーマが原因の場合もあるため、エラーが wp-content 配下のファイルで出るならそのプラグインを無効化するか、開発元に PHP バージョン要件を問い合わせるのが早い。

この記事のポイント

  • 画面真っ白と unexpected ‘?’ 構文エラーは PHP 5.x 系で発生しやすい
  • まず phpinfo() で現在の PHP バージョンを調べ、7.4 以上に切り替える
  • サーバー管理画面の PHP セレクターかサポート依頼でバージョンを上げる
  • 切り替え後も直らなければコアファイルの再アップロードと mu-plugins の調査を
  • WordPress 7.0 なら PHP 8.0 以降の利用が推奨される
GoogleとMicrosoftがAIエージェント共通仕様ARDを公開、11社が賛同

GoogleとMicrosoftがAIエージェント共通仕様ARDを公開、11社が賛同

GoogleとMicrosoftを含む11社が、AIエージェントがウェブ上のツールやスキルを自動検出するための共通仕様「ARD(Agentic Resource Discovery)」を2026年6月17日に公開した。

GitHubやHugging Face、NVIDIA、Salesforceも名を連ねるこの仕様は、各社が公開するAIエージェント向け機能を、事前の手動接続なしに実行時に見つけ出せる仕組みだ。Apache 2.0ライセンスで公開され、同日に複数の参照実装もリリースされた。

この仕様が実用化されれば、AIエージェントは必要なツールを自ら探し出して接続できるようになる。開発者やサービス提供者にとっては、自社のAPIやエージェント機能をAIシステムに自動的に見つけてもらうための新たな方法が生まれることになる。

ARDとは何か

ARDとは何か

ARD(Agentic Resource Discovery)は、AIエージェントがウェブ上で「使えるツールや機能」を自動的に見つけ出すための共通ルールを定めた仕様だ。Linux Foundationのワーキンググループが管理するAI Catalogデータモデルを基盤に構築されている。

現在のAIエージェントは、あらかじめ各ツールやMCPサーバー、APIとの接続を手動で設定する必要がある。企業が公開する機能が増え続けるなか、この「事前配線」方式では拡張性に限界があった。ARDはこの問題に対処するために設計されている。

現状の方式(Before)
開発者 各ツールを手動で登録
API A API B MCPサーバー
※AIエージェントが使えるツールを事前に1つずつ配線する必要がある
ARD導入後(After)
開発者 カタログファイルを1つ設置するだけ
AIエージェント レジストリ検索 自動接続
※実行時に必要なツールを自動検出して接続する

ARDの仕組みは、企業が自社ドメインに公開するカタログと、それを収集してインデックス化するレジストリの2層構造で成り立っている。人手による接続設定を実行時の検索に置き換えることで、AIエージェントが自律的に機能を発見できる世界を目指している。

ARDの技術的な仕組み

ARDの技術的な仕組み

カタログとレジストリの2層構造

ARDの中核は「カタログ」と「レジストリ」という2つの要素だ。まず、ツールやエージェントを提供する企業は、自社ドメインの定められたパスにai-catalog.jsonというファイルを設置する。このファイルには、公開するツール、MCPサーバー、エージェント、APIの一覧が記述される。

次に「レジストリ」がこれらのカタログを巡回(クロール)してインデックス化する。AIエージェントが「この処理に使えるツールはないか」と自然言語で問い合わせると、レジストリが該当するカタログ情報を返す仕組みだ。

STEP 1 企業が自社ドメインに ai-catalog.json を設置
STEP 2 レジストリがカタログをクロール・インデックス化
STEP 3 AIエージェントが自然言語でレジストリに問い合わせ
STEP 4 該当ツールが見つかればエージェントが直接接続

カタログが公開者の自社ドメインに置かれることで、ドメイン所有権が公開者の検証手段として機能する。本番運用では、暗号化された信頼メタデータを付与し、接続前に公開者の身元を確認することも可能だ。ツールが選定された後は、ARDの役割は終了し、実際の接続は各ツール固有のプロトコルで直接行われる。

誰に向けた仕様なのか

ARDが主に対象とするのは、APIやMCPサーバー、エージェントといった「呼び出し可能な機能」を提供する企業だ。ツールを公開する企業には、AIエージェントに見つけてもらい、信頼してもらうための明確な方法が提供される。

一方、一般的なコンテンツサイトにとっては、現時点で直接的な活用方法は示されていない。Search Engine Journalの記事でも「典型的なコンテンツサイトに今日すぐ取るべきアクションはない」と指摘されている。

公開当日に登場した参照実装

公開当日に登場した参照実装

ARDの草案公開と同日に、複数の参加企業が実際に動作するツールをリリースした。

  • GitHub Copilot向けに「Agent Finder」を導入。選択したレジストリからMCPサーバー、スキル、ツール、エージェントを検出し、ユーザーが接続対象を制御できる仕組みだ。
  • Hugging Face ARDサービス全体からスキルやMCPサーバーを検索する「Discover Tool」を公開した。
  • Cisco Linux Foundation傘下のオープンソースプロジェクト「AGNTCY Agent Directory」にARDを統合した。

GitHubのAgent Finderは特に関心を集めている。Copilotのユーザーがレジストリから必要な機能を見つけ出し、自分の判断で接続を許可できる設計は、エージェントの自律性とユーザー制御のバランスを取る試みといえる。

この流れは、ウェブの「機械可読層」を整備する一連のオープン仕様の延長線上にある。GoogleはARD公開の2日前にも、AIシステム間で組織知識を共有するための「Open Knowledge Format」仕様を発表している。いずれも自社ドメインに構造化ファイルを設置するだけで、AIシステムが人手の配線なしに情報を利用できるようにする考え方だ。

Googleの立ち位置と今後の展開

Googleの立ち位置と今後の展開

GoogleはARDにおいて、Gemini Enterprise Agent Platformの一部である「Agent Registry」を中心的な役割として位置づけている。これはエージェント向けリソースのホスティングと検索、企業向けのガバナンス管理を担う基盤だ。

Search Engine Journalの記事によれば、Agent RegistryへのネイティブARD対応は数カ月以内に予定されている。これが実現すれば、組織は内部レジストリを広域ネットワークに接続できるようになる。

ただし現時点でこの対応は稼働しておらず、ARDはあくまで「仕様」であってGoogle検索の機能ではない。検索エンジンとしてのGoogleがARDカタログを直接検索結果に反映するわけではない点は、区別して理解しておく必要がある。

コンテンツ制作者が今考えるべきこと

コンテンツ制作者が今考えるべきこと

ARDがもたらす影響は、ビジネスの性質によって大きく異なる。ツールやAPIを提供する企業には、AIエージェントに発見されるための具体的な手段が用意された。一方で、一般的なコンテンツサイト運営者にとっての即効性は限定的だ。

この仕様の価値については業界内でも議論がある。GoogleのJohn Mueller氏は、LLMシステムがllms.txtのようなファイルでサイトを区別することはできないと指摘し、将来のエージェント向け戦略よりも現在のニーズに注力するよう助言している。ARDが対象とするのはツールやエージェントであり、コンテンツではないという点は、こうした議論の背景として押さえておきたい。

仕様はまだv0.9草案であり、GitHubリポジトリで変更提案を受け付けている段階だ。実用性を左右するのは、カタログを大規模にクロールしてインデックス化できるレジストリのエコシステムだが、それもまだ初期段階にある。

エコシステムが成熟した場合に最も恩恵を受けるのは、他者が必要とするツールやエージェントを提供する企業だ。GoogleがUlrtaユーザー向けに展開し始めたエージェント主導の検索機能も、この方向性を示唆している。今すぐ取るべき現実的なアクションは、自社が使っているプラットフォームやツールがARDに対応するかどうか、そして対応時にどのような公開情報が求められるかを注視することだ。

この記事のポイント

  • ARDはAIエージェントがツールやAPIを実行時に自動発見するためのオープン仕様である
  • カタログ(ai-catalog.json)とレジストリの2層構造で、ドメイン所有権が信頼の基盤となる
  • GitHubやHugging Faceが公開初日から参照実装を提供しており、実用化に向けた動きは速い
  • 一般的なコンテンツサイトよりも、ツールやAPIを公開する企業に直接的な恩恵がある
  • v0.9草案段階であり、レジストリのエコシステム構築が今後の鍵を握る
WordPressでショートコードが表示されず文字列だけ出る時の直し方

WordPressでショートコードが表示されず文字列だけ出る時の直し方

WordPress 7.0 でショートコードが表示されず、角括弧付きの文字列がそのまま画面に出る場合、プラグインの停止・テーマの出力フィルタ不足・ブロックエディタとの相性が主な原因だ。直すにはプラグインの更新や有効化確認から始め、テーマ側で処理されていないときは強制実行のコードを functions.php に追加する。

なぜショートコードが表示されず文字列だけ出るのか

なぜショートコードが表示されず文字列だけ出るのか

ショートコードは [example] のような角括弧で囲まれた短い文字列で、WordPress が表示の瞬間に対応する PHP 処理や HTML に置き換える仕組みだ。この置き換えが行われず、角括弧付きのまま表示される場合、大きく分けて三つの原因が考えられる。

原因1 ショートコードを登録しているプラグインが停止している

プラグインが無効化されているか、WordPress 7.0 への更新後に互換性の問題で停止しているケースが最も多い。更新直後にサイトが「このサイトで重大なエラーが発生しました」という表示になった場合、WordPress は自動で問題のプラグインを停止する。この自動停止によってショートコードの登録処理が丸ごと抜け落ち、文字列だけが残る。

また、プラグインは有効に見えても、特定のページタイプ(固定ページ・投稿・カスタム投稿タイプ)で意図的にショートコードの置換を制限している設計もある。管理画面のプラグイン一覧で有効化状態を確認しても原因がわからないときは、プラグインの内部ロジックまで疑う必要がある。

原因2 テーマが本文中のショートコードを処理していない

ショートコードの置換は do_shortcode() という関数を通じて実行される。WordPress の標準ループやウィジェットエリアでは自動で処理されるが、テーマがカスタマイズされたテンプレートで直接 get_post_meta()the_content() を独自に加工している場合、この関数が呼ばれずショートコードが展開されない。とくに自作テーマや子テーマでカスタムフィールドの値を表示する箇所で起きやすい。

原因3 ブロックエディタの「ショートコードブロック」未使用

WordPress のブロックエディタ(Gutenberg)でショートコードを機能させるには、専用の「ショートコード」ブロックの中に記述する必要がある。段落ブロックや見出しブロックに直接 [example] と打ち込んだ場合、ブロックの保存・出力の仕様によってはテキストとしてそのまま表示されることがある。クラシックエディタに慣れていると見落としがちなポイントだ。

ショートコードが表示されないときの原因3分類
原因 A プラグインが無効化または停止している
原因 B テーマが do_shortcode() を呼んでいない
原因 C ブロックエディタでショートコードブロックを使っていない
プラグイン停止  テーマ側の処理不足  ブロック種別の選択ミス

上図の三方向から原因を絞り込めば、ほとんどのケースで該当箇所が見つかる。次項からは実際の対処手順を具体的に解説する。

ショートコードが機能しないときの具体的な対処手順

ショートコードが機能しないときの具体的な対処手順

手順1 プラグインの有効化と更新を確認する

管理画面の「プラグイン」→「インストール済みプラグイン」を開き、該当プラグインが有効化されているかを確認する。無効化されていれば「有効化」をクリックするだけで解決することが多い。有効化されているのに直らない場合は、プラグインの最新バージョンがリリースされていないか更新画面を確認する。WordPress 7.0 へのメジャーアップデート直後は、プラグイン開発者が緊急の互換性アップデートを出している可能性が高い。

管理画面にアクセスできないほどサイトが壊れている場合は、WordPress の「リカバリモード」を利用する。サイトで致命的エラーが発生すると、管理者メールアドレス宛に「このサイトで重大なエラーが発生しました」という件名のメールが届き、その中にリカバリモード用の特別なログインリンクが記載されている。このリンクからログインすると、問題のプラグインだけが停止した状態で管理画面に入れる。

手順2 テーマ側で do_shortcode() を明示的に実行する

プラグインが正常に動作しているのにショートコードが展開されない場合、テーマのテンプレートが原因だ。該当のショートコードを表示したい箇所がカスタムフィールドやウィジェットエリア内であれば、テンプレートファイル内の出力部分に do_shortcode() を追加する。

// カスタムフィールドの値をショートコード展開して出力
echo do_shortcode( get_post_meta( get_the_ID(), 'my_custom_field', true ) );

// 本文中のショートコードを意図的に再実行(通常は不要だが保険として)
echo do_shortcode( get_the_content() );

上記は functions.php ではなく、該当のテンプレート(single.phppage.php など)の出力箇所に追記するコードだ。子テーマを使っていない場合は必ず子テーマを用意してから編集し、テーマのアップデートで変更が失われないようにする。子テーマの作り方は後述の FAQ で扱う。

手順3 ブロックエディタで「ショートコード」ブロックを使う

ブロックエディタでページを編集している場合、ブロック挿入ツール(+ボタン)から「ショートコード」ブロックを検索して追加する。既存の段落ブロックに直接ショートコードを打ち込んでいる場合は、そのブロックを削除して新しくショートコードブロックを追加し、中にショートコード文字列だけを入力する。

STEP 1 ブロック挿入ツール(+)をクリック
STEP 2 「ショートコード」ブロックを検索して追加
STEP 3 ブロック内にショートコード(例: [example])を入力
STEP 4 プレビューまたは公開して表示を確認

この手順でブロックエディタ上の問題は解決するが、テーマ側の出力処理に起因する問題はこれだけでは直らない。手順2も併せて確認するのが確実だ。

WordPress 7.0 特有の注意点と想定外のエラーへの備え

WordPress 7.0 特有の注意点と想定外のエラーへの備え

WordPress 7.0 は内部のエラーハンドリングが強化され、従来は警告レベルで済んでいた処理が致命的エラーとして扱われるケースが増えている。プラグインが最新でも、内部の非推奨関数の呼び出しや PHP バージョンとの不一致があると、サイト全体がダウンし管理画面からも締め出される。

こうした状況では、FTP またはサーバーのファイルマネージャーで /wp-content/plugins/問題のプラグインフォルダ/ を一時的にリネームする方法が最も確実な緊急回避策になる。フォルダ名を「custom-profile-picture」から「custom-profile-picture_temp」などに変更すれば、WordPress はそのプラグインを検出できなくなり、サイトが正常に表示される状態まで復帰する。その後、プラグインの互換性情報を確認してから正式な対処を取る。

よくある質問

ショートコードを使うプラグインをアップデートしたらサイトが真っ白になった

WordPress 7.0 とプラグインの互換性が取れていない可能性が高い。リカバリモードのリンクがメールで届いていればそこからログインし、問題のプラグインを停止する。メールが届いていない場合は FTP で対象プラグインのフォルダをリネームし、管理画面にアクセスできる状態に戻してから代替プラグインを検討する。

子テーマの functions.php に追記する方法がわからない

子テーマとは、親テーマの機能を引き継ぎつつ安全にカスタマイズするための仕組みだ。まず親テーマと同じディレクトリに子テーマ用フォルダを作成し、style.cssfunctions.php の2ファイルを設置する。functions.php には親テーマのスタイルを読み込むコードと、do_shortcode() を含むカスタマイズコードを記述する。詳細な手順は WordPress 公式の子テーマ作成ガイドが役立つ。

ショートコードブロックを使っても特定のページだけ表示されない

キャッシュ系プラグインや CDN が原因のことが多い。キャッシュを全削除し、CDN を使用している場合は一時的に開発モードにしてから表示を確認する。また、該当ページがカスタム投稿タイプで、テンプレートが専用の出力処理をしている場合も同様に do_shortcode() の追加が必要になる。

プラグインを更新したが問題が再発した

更新で一度直っても、WordPress の自動エラーハンドリングが再度働いて同じプラグインを停止することがある。サーバーのエラーログを確認し、PHP のメモリ不足や実行時間制限が原因であれば、wp-config.phpWP_MEMORY_LIMIT を 256M 以上に設定する。根本的にはプラグイン開発者の対応を待つ必要があるケースもある。

この記事のポイント

  • ショートコードが文字列のまま表示される主因はプラグイン停止・テーマの処理不足・ブロック選択ミスの3つ
  • 管理画面に入れない場合はリカバリモードか FTP でプラグインフォルダをリネームして復旧させる
  • テーマ側で do_shortcode() が呼ばれていない箇所は子テーマのテンプレートに追記する
  • ブロックエディタでは必ず「ショートコード」専用ブロックの中に記述する
  • WordPress 7.0 はエラーハンドリングが強化され互換性問題が表面化しやすい
Prop For That、CSSで動的プロパティを扱う新ライブラリの全容

Prop For That、CSSで動的プロパティを扱う新ライブラリの全容

CSS-Tricksで紹介された「Prop For That」は、これまでのCSS設計の常識を塗り替える可能性を持つライブラリだ。ブラウザが本来CSS単体では取得できない情報、例えばマウスカーソルの座標やページのスクロール速度、現在時刻などを、あたかもネイティブのカスタムプロパティであるかのように扱えるようにする。開発者はライブラリを読み込み、対象のHTML要素に専用のデータ属性を付与するだけで、これらの動的な値を直接スタイルシートから参照できる。

CSS-Tricksの記事によれば、このライブラリの最大の魅力は、JavaScriptのロジックを意識せずに済む点にある。従来はイベントリスナーで値の変化を監視し、DOMのスタイルを逐次更新するスクリプトが必要だった。Prop For Thatを使えば、宣言的にCSSを記述する感覚のまま、高度なインタラクションを実装できる。本記事では、この新しいアプローチの仕組みや具体的な活用方法、そして現場への影響を掘り下げていく。

Prop For Thatが解決する根本的な課題

Prop For Thatが解決する根本的な課題

CSSは本来、ページが読み込まれた時点の静的なスタイルを定義する仕組みであり、ユーザーの操作に応じて刻一刻と変化するブラウザの内部状態を直接知覚できない。マウスポインターの位置、ページのどこまでスクロールしたか、特定のフォーム要素が今フォーカスを持っているかといった情報は、すべてJavaScriptの領分だった。この断絶が、アニメーションやインタラクションを実装する際のボトルネックになっていた。

従来のアプローチ(Before)
JavaScriptでイベントを監視し、スタイルを都度書き換える必要があった
開発者 JSで状態取得 DOMのstyleプロパティ書き換え
課題ロジックとスタイルの分離が難しく、コードの見通しが悪くなる
Prop For Thatのアプローチ(After)
HTML属性を付与するだけで、CSSカスタムプロパティとして値を参照できる
開発者 data-props-for属性を付与 Prop For That CSS変数を自動更新
効果スタイルシート内で完結し、コードの凝集度が高まる

このデモが示すように、Prop For ThatはHTMLとCSSだけの世界観を維持したまま、動的な値を扱える設計思想を持つ。これは単なるユーティリティの追加ではなく、スタイリングの責務をCSSに取り戻すパラダイムシフトだ。

主要なライブプロパティとその仕組み

ポインタートラッキングで実現する追従型インタラクション

マウスカーソルの動きをCSSだけで捉えられると、ボタンのホバーエフェクトや視差効果の表現力が格段に上がる。Prop For Thatでは、data-props-for="pointer"という属性を設定した要素に対して、--live-pointer-x--live-pointer-yという2つのカスタムプロパティが動的に注入される。

<div class="mover" data-props-for="pointer">...</div>
ポインター追従の概念
data-props-for=”pointer” –live-pointer-x –live-pointer-y
使用例 要素の位置をカーソルに追従させる
left: calc(var(--live-pointer-x, 0) * 1px);
top: calc(var(--live-pointer-y, 0) * 1px);

これらの値はリアルタイムに更新されるため、要素をposition: absoluteで配置しておけば、CSSの計算式だけで物体がカーソルを追いかける動きを表現できる。マウスの速度に応じてスタイルを変化させるなど、従来は複雑なスクリプトが必要だった演出が、数行のスタイル宣言で完結する。

スクロールベロシティと現在時刻の活用

スクロールの勢いを表すベロシティ(速度)や、刻々と変化する現在時刻も、ライブプロパティとして取得できる。これらを活用すれば、ユーザーがページを勢いよくスクロールしているときだけ特定のアニメーションを発動させたり、時刻に応じて配色を動的に切り替えるといった演出が、CSSの範囲内で実装可能になる。

/* スクロール速度に応じて要素の透明度を変化させる例 */
.scroll-aware {
  opacity: calc(var(--live-scroll-velocity, 0) * 0.01);
  transition: opacity 0.3s ease;
}
スクロールベロシティ
–live-scroll-velocity スクロールの勢い(px/frame)
用途勢いのあるスクロール時だけ要素を強調表示する
現在時刻
–live-time-seconds 秒単位の現在時刻
用途時間帯に応じたダークモードへの自動切り替え

CSS-Tricksの記事で特に評価されていたのは、スクロールにモメンタム(慣性)の概念を持ち込める点だ。ユーザーの操作に物理的な手応えを感じさせる、いわゆる「気持ちいいインタラクション」の実装ハードルが大きく下がる。

実装のポイントとコード例

実装のポイントとコード例

基本的なセットアップ手順

導入は極めてシンプルだ。ライブラリをプロジェクトに読み込んだあと、動的な値を取得したい要素にdata-props-for属性を追加する。あとは通常のCSSカスタムプロパティと同じ感覚で、var()関数を使って値を参照すればよい。

<!-- HTML側 -->
<div class="tracker" data-props-for="pointer">
  この要素がカーソルを追跡する
</div>

/* CSS側 */
.tracker {
  position: absolute;
  width: 60px;
  height: 60px;
  background: #3498db;
  border-radius: 50%;

  /* ライブプロパティを参照して位置を動的に計算 */
  left: calc(var(--live-pointer-x, 0) * 1px - 30px);
  top: calc(var(--live-pointer-y, 0) * 1px - 30px);

  /* スムーズな追従のためのトランジション */
  transition: left 0.1s ease-out, top 0.1s ease-out;
}
設定フロー(After)
STEP 1 ライブラリをimportする
STEP 2 HTML要素にdata-props-for属性を追加
STEP 3 CSSでvar()を使ってライブプロパティを参照

このコード例では、カーソルを追いかける円形の要素を定義している。注意すべきは、var()の第2引数でフォールバック値(ここでは0)を指定している点だ。ライブラリが読み込まれる前や、何らかの理由でプロパティが未定義の場合でも、要素が想定外の位置に飛ぶのを防げる。

パフォーマンス上の配慮

ライブプロパティは高頻度で更新されるため、lefttopのようなレイアウトを再計算させるプロパティの変更は、パフォーマンスの観点から注意が必要だ。可能であればtransformプロパティで位置を制御するほうが、ブラウザの合成処理に乗り、再描画コストを抑えられる。

/* パフォーマンスを考慮した書き方 */
.optimized-tracker {
  position: absolute;
  width: 60px;
  height: 60px;
  background: #e74c3c;
  border-radius: 50%;

  /* transformを使えばGPU合成で高速に描画される */
  transform: translate(
    calc(var(--live-pointer-x, 0) * 1px - 50%),
    calc(var(--live-pointer-y, 0) * 1px - 50%)
  );
}

このtransformによる制御は、特に多数の要素を同時に動かす場合や、モバイル端末での動作を考慮する際に有効だ。CSS-Tricksの紹介するデモ群でも、このベストプラクティスが採用されている。

Web制作の現場に与える影響

Web制作の現場に与える影響

JavaScriptとCSSの新たな役割分担

Prop For Thatの登場は、フロントエンド開発におけるJavaScriptとCSSの役割分担を見直す契機になる。従来は「動的なものはJavaScript、静的なものはCSS」という暗黙の線引きがあった。しかし、このライブラリが示す方向性は、表示やスタイルの変化はCSSに寄せるという考え方だ。

従来の役割分担(Before)
JavaScript 動的なスタイル変更を一手に担う
CSS 静的なスタイル定義のみ
これからの役割分担(After)
JavaScript データの取得や状態管理に専念
CSS 動的なスタイル変更も含めて表示の責務を担当

これは単なる書き方の変化ではない。コードの凝集度が高まり、スタイルに関するロジックがCSSファイルに集約されることで、メンテナンス性が向上する。特に、複数人で開発する大規模プロジェクトや、インタラクションの多いランディングページの制作では、このメリットが顕著に現れる。

プロトタイピングスピードの加速

CSS-Tricksの記事が高く評価していたもう一つの側面は、プロトタイピングの速さだ。アイデアを思いついてから、実際にブラウザ上で動くモックアップを作るまでの時間が大幅に短縮される。複雑なJavaScriptの設定なしに、HTMLとCSSだけでリッチなインタラクションを試せることは、クリエイティブな探求の敷居を大きく下げる。

この手軽さは、デザイナーがコーディングに踏み出すきっかけとしても機能するだろう。また、クライアントワークの現場では、「この動きを実装するのにどれだけの工数がかかるか」という見積もりの精度も変わってくる。これまでスクリプトの作成で1日かかっていた表現が、数時間のコーディングで実現できる可能性があるからだ。

この記事のポイント

  • Prop For Thatは、マウス位置やスクロール速度などブラウザの動的情報をCSSカスタムプロパティとして参照できるライブラリである
  • 導入はライブラリの読み込みとHTML属性の追加のみで、JavaScriptの記述を必要としない
  • ポインタートラッキング、スクロールベロシティ、現在時刻など、多彩なライブプロパティが用意されている
  • パフォーマンスを考慮する場合は、lefttopではなくtransformで位置制御するのが推奨される
  • JavaScriptとCSSの役割分担を見直し、スタイルの責務をCSSに集約する設計思想が背景にある
  • プロトタイピングの高速化や、インタラクション実装の工数削減といった実務的なメリットが大きい