
WordPressのカスタムブロックを作ろうとして、最初のビルドで止まってしまった経験はありませんか。@wordpress/create-blockでプロジェクトを生成し、npm installを走らせた瞬間にERESOLVE unable to resolve dependency treeが出て頭を抱えたり、ACF Blocksで登録したはずのブロックが編集画面では表示されるのにプレビュー部分が真っ白で、PHPのどこを疑えばいいか分からなくなったり。どちらも、私がこの5年で何度も相談を受けてきた「あるある」です。
そして、こうした最初のつまずきを一度経験すると、多くの方が「Reactは難しすぎる」「ACFは挙動が読めない」と極端に振り切った結論を出しがちです。しかし実際には、両者は対立する選択肢ではなく、プロジェクトの形に応じて使い分ける道具です。あなたが今、どちらに手を伸ばすべきか悩んでいるなら、まずは両者の設計思想と運用感覚の地続きな違いを整理していきましょう。
「ReactかACFか」は宗教戦争ではない。プロジェクトの特性と、運用に乗せたあとの保守コストまで含めて天秤にかけるのが、後悔しない選び方だ。
Reactによるネイティブ開発:学習コストと引き換えに手にするエディタ体験
Reactベースのカスタムブロック開発は、最初にそれなりの壁があります。@wordpress/create-block my-blockでプロジェクトを初期化し、wp-env startでローカルDocker環境を立ち上げて、block.jsonにメタ情報を書き、edit()関数とsave()関数をJSXで記述し、最後にnpm run buildでプロダクション用アセットを吐き出す。この一連の流れを覚えるだけで、PHPに慣れた方にとっては相応の覚悟が必要です。
とくにNode.jsのバージョンが合わないことによる依存解決エラーは本当につきもので、Node 16系で動いていたコードがNode 20系に上げた瞬間にビルドが通らなくなる、というのも私が相談を受けてきた定番の失敗パターンです。nvmなどでプロジェクトごとにNodeバージョンを固定する仕組みを、最初からチームで揃えておくのが、結果的に大きな時間を取り戻します。
ただし、ここでいう難しさは、Reactの文法だけを指しているわけではありません。実際の現場で詰まりやすいのは、次の要素が一度に登場することです。
- JSXでの表示ロジックとコンポーネント設計
block.jsonと属性定義の考え方edit()とsave()の役割の違い- WordPressのデータ保存形式とHTMLの整合性
- npm、ビルド、依存パッケージの管理
- エディタ内と公開画面の表示差分
PHPでテンプレートを書いてきた人にとって、サーバー側でHTMLを組み立てる発想と、エディタ上でコンポーネントを動かす発想はかなり異なります。最初からすべてを理解しようとすると、ブロックを一つ作る前に開発環境の説明だけで疲れてしまう。まずはテキスト入力、画像選択、リンク設定のような小さな要素から始め、属性がどのタイミングで保存され、編集画面でどう読み出されるかを確認した方が、理解は早く進みます。
しかし、この初期投資を乗り越えると、エディタ上の体験は劇的に変わります。InnerBlocks APIを使えば他のブロックを内包できますし、InspectorControlsを使えばブロック選択時のサイドバーにオリジナルの入力UIを追加できます。クライアントワークで「編集中の見え方」と「公開後の見え方」のギャップを最小化したいとき、この一貫性は想像以上に効いてきます。ブロック編集、保存、プレビュー確認のループが短くなるほど、クライアントとの認識すり合わせにかかる工数は下がります。
InnerBlocksと属性設計が編集体験を決める
Reactネイティブの強みは、見た目を作れることだけではありません。編集者がどの順番で、どの情報を、どこで入力するのかまで設計できることにあります。
たとえば、カードを3枚並べるブロックを作る場合、単純にタイトルや画像のURLを一つの配列に詰め込むこともできます。しかし、それでは編集画面での再利用性や、カード単位の編集操作が扱いにくくなります。カード自体を子ブロックに分け、親ブロックではレイアウトだけを管理する設計にすると、編集者は個々のカードを直感的に扱いやすくなります。
一方、自由度を上げすぎると、編集者が意図しない組み合わせを作れてしまう問題も出ます。InnerBlocksで何でも入れられるようにするのではなく、許可するブロックを絞る、テンプレートを用意する、編集画面での説明を加えるといった制御が必要です。Reactを選べば自由になる、というより、自由になった分だけ設計者の責任が増えると考えた方が近いでしょう。
さらに、block.jsonに記述するattributesスキーマは、ブロックが受け取れる値の「契約」として機能します。type: "string"、type: "boolean"、type: "array"といった型を宣言できるため、後から別の方がコードを読んでも「このブロックは文字列と真偽値と繰り返しフィールドを受け取る」と理解しやすい。これはドキュメントとしての役割も果たします。
ただし、属性を増やせば増やすほど良いわけではありません。表示に使わなくなった属性を残したままにすると、後からデータ構造を変更するときに負担になります。ブロックの初期設計では、将来使うかもしれない項目を先回りして詰め込むより、実際の編集操作に必要な値を見極める方が安全です。
WordPressコア自体がブロックパターンを通じて「再利用可能な編集体験」を推し進めている以上、コアAPIに沿った書き方を選ぶことには、長期的な保守性という意味でも合理性があります。
Reactネイティブは「最初のセットアップが重い」が、完成したブロックはエディタと地続きで動く。これが後工程の体験を根本から変える。
ビルドを個人の記憶に依存させない
見過ごせないのが、ビルドプロセスの存在です。npm run buildを忘れて本番環境に古いアセットが上がった、という事故はReactネイティブ開発につきものです。開発者のローカル環境では動いているのに、納品環境では古いJavaScriptが読み込まれている。こうした問題は、コードのバグというより、リリース手順の設計不足から起きます。
チームで開発する場合、このビルドフローを個人の手作業に依存させず、GitHub ActionsやGitLab CIなどに組み込んで再現性を担保しておくのが安心です。package.jsonのscriptsにbuildを明示し、Node.jsのバージョンとパッケージマネージャーを固定する。ロックファイルをリポジトリに含め、誰が作業しても同じ依存関係を再現できるようにする。このあたりは地味ですが、Reactを採用するなら避けて通れません。
開発環境にDockerを使う場合も、WordPress側の環境とNode.js側の環境を混同しないことが大切です。wp-envでWordPressを立ち上げても、Node.jsの依存関係まで自動的に揃うわけではありません。PHPのバージョン、WordPressのバージョン、Node.jsのバージョンをそれぞれ記録し、どの環境が何を担当しているのかをチームで共有しておくと、初歩的な環境差分による事故を減らせます。
ACF Blocksの強みと限界:PHP主導で実現する高速な開発サイクル
一方、ACF Blocksは発想が根本的に異なります。acf_register_block_type()をfunctions.phpに書き、render_callbackで普段使い慣れているPHPテンプレートを返す。フィールドグループは管理画面のGUIで組み立てる。JavaScriptを書く必要がない構成なら、PHPを主戦場にしてきた方にとっては何よりの安心材料でしょう。
とくに管理画面でフィールドを追加・並べ替え・条件付きで表示制御できる体験は、Reactで同等機能を作ろうとしたら、入力UIや状態管理まで含めて相応の実装が必要になることを思えば、開発スピードの差は明らかです。Repeaterで繰り返しの子フィールドを持てば、「スライドショーの画像リスト」のような構造もGUI中心で表現できますし、Flexible Contentでブロック型のレイアウトを切り替えられるようにすれば、ページビルダーに近い編集体験も実現できます。
「クライアントが現場でフィールド構成を変えたいと言っている」ようなケースでも、ACFならその場で対応できる柔軟性があります。もちろん、編集者が自由にフィールドを変更できる状態をそのまま本番運用に持ち込むのは危険です。フィールド名や返り値の形式を変更すれば、既存のテンプレートが壊れる可能性があるからです。GUIで変更できることと、無制限に変更してよいことは別の話です。
そして何より、render_callbackが返すテンプレートは、普段のテーマ開発と同じ世界です。the_title()、get_field()、WP_Query、wp_localize_script()など、既存のPHP資産を活用できます。テーマの他のテンプレートと変数を共有しやすい、フックを仕掛けやすい、データベース設計の延長で物事を考えられる。これはPHPでWordPressサイトを長く作ってきた方にとって、見逃せないアドバンテージになります。
get_field('heading', $post->ID)のような書き方は、ブロック内外の境界を曖昧にして、既存のテンプレートヘルパーを使い回せる素地を作ってくれます。既存サイトにACFのフィールドやテンプレートが大量にある場合、Reactネイティブへ全面移行するより、ACF Blocksを追加した方が自然なケースも多いでしょう。
ACF Blocksのデメリットは「速いこと」ではなく、速さの後に出る
ACF Blocksの弱点も明確に存在します。まず、ACF PROは有料ライセンスであることです。クライアントの予算にこのライセンス費が乗せられるかどうかは、最初の段階で確認しておくべきポイントでしょう。年間保守契約の中に組み込むのか、初回開発費に含めるのか、クライアント側で契約してもらうのか。技術の話だけでなく、契約と運用の話として整理しておきたいところです。
また、エディタ上でのプレビュー挙動がReactネイティブほど滑らかでないことは、触ってみると分かります。フィールド値を変更するたびに、保存や更新を挟んで公開側のレンダリング結果を確認する場面があり、編集中のリアルタイム性は劣ります。最近の構成ではエディタ側の表示を工夫できる余地もありますが、ACF Blocksを使えば自動的にReactと同じ編集体験になるわけではありません。
とくに「ブロック内のアイテムを視覚的にドラッグで並べ替える」「ブロック同士を多段にネストする」「入力値に応じてその場で複雑な表示を切り替える」といったインタラクションは、ACF Blocksだけでは実装が現実的でないことがあります。結局はカスタムJavaScriptを書くか、Reactの助けを借りることになる。ここまで来ると、PHPだけで速く作れるというACFの前提が崩れてきます。
もう一つ、ACF Blocks特有の見落としポイントとして、フィールド値のサニタイズがrender_callbackに委ねられる点を挙げておきます。ACFから返ってきた値をそのままHTMLに埋め込んでよいわけではありません。テキストとして出すならesc_html()、属性値ならesc_attr()、許可したHTMLを含めるなら用途に応じてwp_kses_post()を使う。URLにはURL向けのエスケープを使う。値の種類と出力先を見ながら処理する必要があります。
「とりあえず動いたから」とサニタイズを後回しにすると、XSSの入り口になる可能性があります。とくにRepeaterの中にユーザーが自由記述できるテキストエリアを含める場合は要注意です。管理画面で入力できる人が信頼できる担当者であっても、将来的に権限を持つ人が増える、データを移行する、外部から値を取り込むといった変更は起こります。公開側での出力時に、用途に合ったエスケープを行うことを標準手順にしておくべきです。
2024年以降の環境変化とプラグイン依存のリスク管理
ここで、2024年10月以降に起きた出来事と、その後の動きを整理しておく必要があります。WordPress.orgはACFをフォークしたプラグインを公開し、Secure Custom Fields(SCF)という名称で提供しています。ここは誤解されやすいのですが、SCFはWordPress本体に同梱された機能ではありません。ACFの代替候補として利用する場合も、通常のプラグインと同じように、対象サイトへ別途インストールして有効化する必要があります。
つまり、「WordPress.orgが公開したACFフォークのプラグイン」と説明するのが正確です。WordPress本体を更新すれば自動的にフィールド機能が追加される、あるいは追加インストールなしで管理画面から使える、と考えてはいけません。SCFを採用する場合は、プラグインの導入手順、バージョン管理、更新時の検証、既存ACFとの互換性を、プロジェクトの運用設計に含める必要があります。
この区別は、単なる呼び方の問題ではありません。「本体同梱だから将来も安心」と誤認したまま構成を決めると、納品後の保守担当者が必要なプラグインを把握できず、ステージング環境だけフィールドが表示されないといった事故につながります。WordPress本体、テーマ、ACF、SCF、その他の拡張プラグインは、それぞれ別の更新単位として扱うべきです。
SCFへ移行できるかどうかは、ACF PROの独自機能にどれだけ依存しているかによって変わります。Repeater、Flexible Content、Clone、Gallery、ACF Blocks周辺の機能などを多用している場合、単純にプラグインを入れ替えれば終わるとは限りません。フィールド定義とテンプレートの書き換えが必要になったり、一部の表現がそのまま再現できなかったりする可能性があります。
既存のACFデータがデータベースに保存されているからといって、別のプラグインがすべての機能や管理画面の挙動を同じように扱えるとは限りません。移行を検討するなら、まず本番サイトの複製環境で、次のような項目を確認する必要があります。
- 既存フィールドの値が正しく読み出せるか
- RepeaterやFlexible Contentの階層が崩れないか
- 画像、投稿オブジェクト、タクソノミーなどの返り値が想定どおりか
- ブロックの編集画面と公開画面の表示が一致するか
- フィールド更新後に既存テンプレートがエラーを起こさないか
- 将来の担当者がフィールド定義を追跡できる状態か
この事実は、「便利なプラグイン一つに依存することの本質的なリスク」を改めて浮き彫りにしています。Reactネイティブで書いたブロックは、WordPressコアのブロックAPIを中心に成立させられるため、特定プラグインのライセンスや開発方針に左右されにくい。逆に、ACF Blocksは便利さの見返りとして、ACFまたはSCFという外部プラグインの更新方針に依存します。
もちろん、コアAPIを使っているからといって、将来の動作が完全に保証されるわけではありません。WordPress本体の仕様変更、ブラウザ環境の変化、依存ライブラリの更新はあります。それでも、依存先をWordPressの標準APIに寄せられることは、保守時の調査範囲を狭める材料になります。
受託案件でクライアントに納品する場合、「このブロックは5年後も10年後も同じ動作をしますか」と質問を受けることは珍しくありません。そのときに、どの機能がWordPressコアに依存し、どの機能がプラグインに依存しているのかを説明できる状態にしておくことが重要です。「ACFだから大丈夫」「Reactだから安心」といった一言で済ませるのではなく、更新対象と代替手段を文書化しておく。これだけでも、将来の引き継ぎはかなり楽になります。
プラグイン依存は開発スピードのショートカットであると同時に、外部要因に保守性を預けることでもある。SCFも本体機能ではなく、導入と更新を管理する対象だ。
現場で選ばれるハイブリッド構成:適材適所のブロック設計術
では、実際の現場ではどうしているのか。ここ数年、私が見てきた中規模から大規模のWordPress案件では、ReactとACFを排他的に選ぶのではなく、明確に役割を分けて使う構成が多くなっています。どちらか一方に統一するルールを敷くチームもありますが、運用に乗ると必ずといっていいほど「ここは逆の方がよかった」という声が出て、結局はハイブリッドに着地します。
判断の軸にしやすいのは、「編集頻度」と「入力複雑度」です。編集頻度が高く、ページの中で何度も組み替えるブロックは、エディタとの一体感を優先してReactネイティブに寄せる。入力項目が多く、値の種類や条件分岐が複雑なブロックは、ACFのフィールド定義を活用する。この二つの軸で考えると、技術選定が好みの話から要件の話に変わります。
たとえば、投稿本文や固定ページのヒーローエリア、CTA、関連記事リスト、著者プロフィールのように「編集者が頻繁に内容を差し替える領域」は、Reactネイティブで実装しやすい部分です。理由は、ブロックパターンや再利用ブロックとの相性が高く、エディタ内のコピーと貼り付けが効くからです。
コンテンツマーケティングを活発に行うクライアントほど、この編集のしやすさは業務効率に直結します。複数のランディングページを共通パターンから展開したい場合、Reactネイティブのブロックをパターン登録しておけば、制作工数を圧縮できます。編集者が公開画面を確認するために何度もプレビューを開く必要がなくなれば、作業の流れも途切れにくくなります。
一方で、クライアント固有の複雑な入力要件は、ACF Blocksが得意です。たとえば不動産サイトの物件スペック表、ECサイトの商品バリエーションの組み合わせ、イベントサイトの開催スケジュール入力などです。入力パターンが細かく、管理画面からの正確な編集が優先される領域では、フィールドタイプを組み合わせた方が早く、入力ミスも抑えやすい。
select、post_object、taxonomy、date_picker、true_falseなどのフィールドを使えば、管理者が入力できる値をある程度制限できます。Reactで同じ入力UIを作る場合、表示、状態管理、バリデーション、保存形式、エラー表示まで設計しなければなりません。もちろんReactで実装する価値があるケースもありますが、単に選択肢を表示するだけなら、ACFの機能を活用する方が合理的です。
| 観点 | Reactネイティブ | ACF Blocks |
|---|---|---|
| 初期セットアップの難度 | やや高い。Node.js、npm、ビルド環境が必要 | 低い。PHPと管理画面の設定を中心に進められる |
| ブロック単体の開発速度 | 基盤を整えた後は安定するが、初期設計が必要 | フィールド構成が決まっていれば非常に速い |
| エディタのリアルタイムプレビュー | 高い。入力値をその場で反映しやすい | 構成によっては保存や再描画を挟む |
| 複雑な入力UIの自由度 | 高い。JSXで細かな体験まで設計できる | GUIで用意されたフィールドの範囲が中心 |
InnerBlocksとの相性 | 高い。ネストや制限を細かく設計できる | 要件によっては追加実装が必要 |
| 既存PHPテーマ資産の活用 | 変換や分離の設計が必要 | 既存テンプレートを流用しやすい |
| 外部プラグインへの依存 | WordPressコアAPI中心で構成できる | ACF Proなどの導入・更新管理が必要 |
| サニタイズ責任 | 保存・表示の両方を設計する | PHPの出力時に開発者が明示的に実施 |
| 長期保守性の見通し | コアAPIに寄せるほど見通しを立てやすい | プラグインの仕様と運用方針に左右される |
この表で大切なのは、Reactがすべての項目で優れている、あるいはACFがすべての項目で劣っているという話ではないことです。Reactは自由度が高い分、設計とビルドの責任が増えます。ACFは速く作れる分、フィールド定義やプラグイン更新の扱いが保守上の論点になります。
ハイブリッド構成では、技術を混ぜること自体よりも、境界を決めることが重要です。同じ種類のブロックを案件ごとにReactとACFで作り分けると、チーム内で判断がぶれます。「編集頻度が高い本文ブロックはReact」「構造化データを入力する管理ブロックはACF」のように、採用基準を短い文章で残しておくと、後から参加したメンバーも迷いにくくなります。
また、ACFを使う場合でも、すべてのロジックをテンプレートに詰め込まないことが大切です。フィールド値の取得、表示用データの整形、HTMLの出力を一つのPHPファイルで処理し始めると、ブロックが増えたときに修正範囲が見えなくなります。テンプレートヘルパーや共通関数を用意し、出力責任を分けるだけでも、ACF Blocksの保守性は変わります。
Reactネイティブでも同じです。ブロックごとに似たような入力コンポーネントを複製していくと、見た目の微調整がすべてのブロックに波及します。共通コンポーネント、デザイン設定、エラーメッセージの扱いを早めに整理しておくと、後からブロックを追加しやすくなります。
プロジェクトの規模とスキルセットから導く開発方針の決定
最後に、あなたが今日決めるべきことを整理しておきましょう。完璧な正解ではなく、納得感のある落としどころを見つけるための判断材料です。
編集者の操作がプロジェクトの中心にあるか
ブロックの主な編集者が開発者本人だけなら、Reactで書いても大きな問題にはなりにくいでしょう。コードを理解している人が入力し、表示崩れが起きたときも原因を追えます。
しかし、クライアントや社内の非エンジニアが編集するなら、管理画面のUXは譲れない要素になります。編集者が「このフィールドには何を入力すればよいのか」を毎回確認しなければならないなら、入力項目のラベルや説明文、選択肢の制御が重要です。ACF BlocksのGUIは、この部分を短い実装で整えやすい。
逆に、編集者がブロックを組み替えながらページ全体を作りたい場合は、Reactネイティブの方が向いていることがあります。ブロックパターン、InnerBlocks、サイドバー設定を組み合わせれば、単なるフォーム入力ではなく、レイアウトを組み立てるための編集体験を作れるからです。
チームの主力スキルセットはPHPかJavaScriptか
既存メンバーがPHP中心で、JavaScriptのビルド環境に不慣れなら、ACF Blocksの方が教育コストを抑えられます。composerでの依存管理とnpmでの依存管理を両方運用する覚悟があるチームなら問題ありませんが、どちらか一方で十分に速いなら、まずはそこに寄せる方が安全です。
一方、フロントエンドエンジニア中心のチームで、Reactの経験が豊富なメンバーがいるなら、Reactネイティブの方が開発はスムーズに進むでしょう。コードレビューの観点でも、レビュアーの主戦場に合わせておく方が品質は安定します。PHPの書き方を知らないメンバーに複雑なrender_callbackを読ませるより、Reactコンポーネントとして設計した方がレビューしやすい場合もあります。
ただし、スキルセットだけで決めると、将来の引き継ぎで困ることがあります。現時点の担当者がReactに詳しくても、保守担当がPHP中心かもしれない。逆に、今はPHP中心でも、今後フロントエンド開発を強化する方針かもしれない。技術選定では、現在の得意分野だけでなく、納品後に誰が触るのかまで考えておきたいところです。
サイトをどのくらい長く運用するのか
5年、10年の運用が前提なら、WordPressコアのブロックAPIに寄せたReactネイティブの方が、特定プラグインへの依存を避けやすくなります。もちろん、Reactを選べば更新作業が不要になるわけではありません。それでも、プラグインのライセンスや開発方針に左右される範囲を小さくできることは、長期運用で効いてきます。
逆に、数年でのリニューアルや別システムへの移行が前提のサイトなら、開発スピードを優先してACFを選ぶ合理性があります。キャンペーンサイトのように運用期間が限定されている案件では、長期保守よりも納期と編集の柔軟性が優先されることがあります。
ただし、短期案件でもデータの出口は考えておくべきです。ACFのフィールドに入れた情報を、将来別のシステムへ移行する可能性があるなら、値の形式や命名規則を雑に決めない方がよい。移行しない前提であっても、同じ案件を別の担当者が引き継ぐことはあります。短期だから何をしてもよい、とはなりません。
最初から大きなブロックを作らない
私のおすすめは、まず一つだけの小さなブロックを両方の方法で試してみることです。たとえば「お問い合わせCTAを表示するブロック」のように、見出し、説明文、ボタンリンク、表示設定程度の構成にします。
Reactで作った場合とACF Blocksで作った場合で、次の点を比べてみてください。
1. 開発環境を立ち上げるまでに、どこで時間がかかったか。
2. 入力UIを作るために、どの程度のコードや設定が必要だったか。
3. 編集者が入力内容を確認しやすいのはどちらか。
4. 公開画面と編集画面の表示差分を直しやすいのはどちらか。
5. 他の担当者がコードと設定を読み解きやすいのはどちらか。
6. ブロックの仕様変更が入ったとき、修正箇所を特定しやすいのはどちらか。
SNS上の意見や他社の事例よりも、その手触りの差の方が判断の決め手になります。比較した結果は、チーム内のドキュメントに残しておいてください。次の案件で同じ議論をするとき、感想ではなく自分たちの実績として使えるからです。
迷ったときに選ぶべきなのは、技術名ではなく運用の形
wordpress カスタムブロック acf react 比較で情報を探すと、Reactを推す記事とACFを推す記事がそれぞれ見つかります。しかし、どちらも自分の案件にそのまま当てはまるとは限りません。Gutenbergの自作ブロックをReactで作る難易度は、チームのJavaScript経験やビルド環境によって変わります。ACF Blocksのデメリットも、エディタ上で複雑なインタラクションが必要か、PHP資産をどれだけ活用できるかで重みが変わります。
Reactネイティブが向いているのは、エディタ体験を細かく設計したい案件、ブロックを長期的にコアAPI中心で保守したい案件、フロントエンド開発の基盤がすでにあるチームです。
ACF Blocksが向いているのは、PHP中心のチーム、既存テーマやフィールド資産を活かしたい案件、構造化された入力を短期間で用意したい案件です。ACF Proを使うなら、ライセンスの扱いと更新担当を決めておく。SCFを検討するなら、本体機能ではなく別途導入するプラグインであることを前提に、互換性を検証する。この一手間を省かないことが大切です。
そして、編集頻度が高いブロックはReact、入力項目が複雑なブロックはACFというハイブリッド構成は、かなり現実的な落としどころです。すべてをReactで書く必要もなければ、すべてをACFに寄せる必要もありません。技術を統一することより、運用上の判断基準を統一することの方が重要です。
どちらの道を選んでも、WordPressのブロック開発では「なぜそれを選んだか」を自分の言葉で説明できる状態が大切です。Reactだから正解、ACFだから手抜き、という話ではありません。プロジェクトの規模、編集者、チームのスキル、運用期間、プラグインへの依存度を並べたうえで、後悔の少ない方を選ぶ。
迷ったら、まず小さなブロックで両方を書いてみてください。書いてみないと見えないものが、必ずあります。
Related reading: theme.jsonとカスタムCSSの競合:ブロックテーマ開発で破綻しないスタイル優先順位の設計ルール and WordPressとヘッドレスCMSの分岐点:個人開発で選ぶべき設計と移行の実態.