2026年8月30日
2026年8月30日
WordPressのwp_enqueue_scriptsでJSとCSSを読み込む方法|依存関係・バージョン・defer指定まで
WordPressでCSSやJavaScriptを読み込むときは、header.php に <link> や <script> を直書きせず、wp_enqueue_scripts フックの中で wp_enqueue_style() / wp_enqueue_script() を呼びます。こうすると、依存関係の順番、同じファイルの二重読み込み防止、キャッシュ対策のバージョン付与、フッターでの読み込みや defer 指定をWordPressがまとめて管理してくれます。この記事では、子テーマでの基本の書き方から、条件付きの読み込み、PHPからJSへの値の受け渡し、管理画面やブロックエディター用のフック、読み込まれないときの確認手順までを順に解説します。
なぜ直書きではなくエンキューするのか
テーマのテンプレートに <script src="..."> を書いても動きはしますが、次のような問題が起こります。
- jQuery など他のスクリプトに依存するファイルが、依存先より先に読み込まれてエラーになる
- プラグインが同じライブラリを読み込み、二重に実行される
- ファイルを更新してもブラウザやCDNのキャッシュが残り、変更が反映されない
- 最適化プラグインやキャッシュプラグインが、そのファイルを結合・遅延の対象として扱えない
エンキュー(読み込み予約)では、ファイルに「ハンドル名」という識別名を付けて登録します。WordPressはハンドル名で重複を判定し、依存関係を解決したうえで、テーマの wp_head() と wp_footer() の位置に出力します。自作テーマで wp_head() / wp_footer() を書き忘れていると何も出力されないので、まずそこを確認します。
基本の書き方(子テーマの functions.php)
<?php
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
function mytheme_enqueue_assets() {
$css_path = get_theme_file_path( 'assets/css/main.css' );
$js_path = get_theme_file_path( 'assets/js/main.js' );
wp_enqueue_style(
'mytheme-main', // ハンドル名
get_theme_file_uri( 'assets/css/main.css' ), // URL
array(), // 依存する CSS
file_exists( $css_path ) ? filemtime( $css_path ) : null // バージョン
);
wp_enqueue_script(
'mytheme-main',
get_theme_file_uri( 'assets/js/main.js' ),
array(), // 依存する JS(jQuery が要るなら array( 'jquery' ))
file_exists( $js_path ) ? filemtime( $js_path ) : null,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
}
ポイントを順に説明します。
- ハンドル名:サイト全体で一意になるよう、テーマやプラグイン固有の接頭辞を付けます。CSSとJSは別々に管理されるので、同じ名前でも衝突しません。
- URLの取得:
get_theme_file_uri()は子テーマに該当ファイルがあれば子テーマ、なければ親テーマのURLを返します。子テーマのファイルを指定したいならget_stylesheet_directory_uri()、親テーマならget_template_directory_uri()を使います。名前が紛らわしく、取り違えると404になる代表的な原因です。 - バージョン:第4引数の値はURLの末尾に
?ver=として付きます。filemtime()でファイルの更新時刻を渡すと、ファイルを変えるたびにURLが変わり、キャッシュが自動で切り替わります。falseを渡すとWordPress本体のバージョンが付き、nullを渡すと何も付きません。 - 第5引数:WordPress 6.3 から配列で
in_footer(フッターで読み込むか)とstrategy(deferまたはasync)を指定できるようになりました。それ以前の書き方のtrue/false(フッターで読み込むかどうか)も引き続き使えます。
子テーマで親テーマの style.css を読み込む
子テーマを作ったとき、親テーマのスタイルが当たらない場合があります。親テーマ側が自分の style.css をどう読み込んでいるかはテーマによって違うため、表示を確認しながら次のように追加します。
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'mytheme-parent',
get_template_directory_uri() . '/style.css',
array(),
wp_get_theme( get_template() )->get( 'Version' )
);
wp_enqueue_style(
'mytheme-child',
get_stylesheet_uri(), // 子テーマの style.css
array( 'mytheme-parent' ), // 親の後に読み込む
wp_get_theme()->get( 'Version' )
);
} );
依存関係に親のハンドル名を入れておくと、子テーマのCSSが後に出力され、上書きが効きます。親テーマがすでに読み込んでいるのに追加すると二重になるので、ページのソースで同じファイルが2回出ていないかを確かめてください。
必要なページだけで読み込む
全ページで読み込むと、使わないページの表示まで遅くなります。wp_enqueue_scripts は表示するページが決まった後に実行されるので、条件分岐タグが使えます。
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_register_script(
'mytheme-contact',
get_theme_file_uri( 'assets/js/contact.js' ),
array(),
'1.0.0',
array( 'in_footer' => true, 'strategy' => 'defer' )
);
if ( is_page( 'contact' ) ) {
wp_enqueue_script( 'mytheme-contact' );
}
} );
wp_register_script() は登録だけを行い、出力はしません。登録しておけば、ショートコードやブロックの中など後の処理から wp_enqueue_script( 'mytheme-contact' ) を呼んで、使う場面だけで読み込めます。
PHPからJSへ値を渡す
AjaxのURLやnonceなど、PHP側の値をJSで使いたい場合は wp_add_inline_script() を使います。before を指定すると、対象のスクリプトより前に出力されます。
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_script( 'mytheme-main' ); // 先に登録済みのハンドル
$data = array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'mytheme_like' ),
);
wp_add_inline_script(
'mytheme-main',
'const mythemeData = ' . wp_json_encode( $data ) . ';',
'before'
);
}, 20 );
値は wp_json_encode() を通してから埋め込みます。文字列をつなげて組み立てると、引用符やタグを含む値でスクリプトが壊れたり、XSSの原因になったりします。wp_localize_script() でも同じことはできますが、本来は翻訳文字列を渡すための関数で、数値も文字列に変換されます。CSSを追加したい場合は wp_add_inline_style( 'mytheme-main', $css ) が使えます。
フロント以外で読み込むフック
wp_enqueue_scripts はフロントエンド用です。場所によってフックが変わります。
admin_enqueue_scripts:管理画面。コールバックに現在の画面を表す$hook_suffixが渡されるので、自分の設定ページだけに絞れます。login_enqueue_scripts:ログイン画面。enqueue_block_editor_assets:ブロックエディターの画面(エディター用のJSなど)。enqueue_block_assets:エディターとフロントの両方。ブロックのスタイルなどに使います。
<?php
add_action( 'admin_enqueue_scripts', function ( $hook_suffix ) {
if ( 'settings_page_myplugin' !== $hook_suffix ) {
return;
}
wp_enqueue_style( 'myplugin-admin', plugins_url( 'admin.css', __FILE__ ), array(), '1.0.0' );
} );
$hook_suffix の値は画面によって決まり、上の例はオプション配下に追加した設定ページの場合です。実際の値は、コールバックの中で一時的にログに書き出すと確認できます。ブロックとして配布するCSSやJSは、block.json の style や viewScript に書く方法もあります。また、ES モジュール形式のスクリプトは WordPress 6.5 から wp_enqueue_script_module() で扱えるようになっています(2026年10月現在)。通常のスクリプトとは依存関係の仕組みが別なので、混在させるときは公式ドキュメントで扱いを確認してください。
defer と async の使い分け
strategy を指定すると、HTMLの解析を止めずにスクリプトを取得できるため、表示の速さに関わる「レンダリングを妨げるリソース」の改善につながります。
- defer:HTMLの解析後、記述順に実行。DOMを操作する多くのスクリプトに向きます。
- async:取得でき次第、順番を問わず実行。アクセス解析のように他と依存しない独立したスクリプト向けです。
依存関係にあるスクリプトのどれかが通常の読み込み(ブロッキング)を前提にしている場合、WordPressは実行順を守るために defer や async を付けないことがあります。指定したのに属性が付かないときは、依存関係を見直してください。読み込み方を変えると動かなくなるスクリプトもあるので、ステージング環境で表示と動作を確認してから本番に反映します。
読み込まれないときの確認手順
可能性の高い順に確認します。
- ページのソースにタグがあるか:ブラウザでソースを表示し、ファイル名やハンドル名で検索します。多くの環境では
<link>にハンドル名-css、<script>にハンドル名-jsという id が付きます。タグ自体が無ければ、フック名の誤り、関数が呼ばれていない、テーマにwp_head()/wp_footer()が無い、のいずれかです。 - URLが404になっていないか:開発者ツールのネットワークタブで確認します。親テーマと子テーマのURL関数の取り違え、パスの誤りが多い原因です。
- 古いファイルが返っていないか:バージョン引数を変える、キャッシュプラグインやCDNのキャッシュを削除する、の順に試します。
- コンソールにエラーが無いか:
jQuery is not definedなら依存関係にjqueryが無い、または読み込み順の問題です。 - 他のプラグインが外していないか:最適化プラグインの結合・遅延設定や、
wp_dequeue_script()で外されていることがあります。一時的に設定を戻して切り分けます。
Query Monitor プラグインを使うと、そのページで登録・出力されたスクリプトとスタイルの一覧や依存関係を確認できます(表示項目の名称はバージョンで変わることがあります)。
まとめ
- CSS/JSは
wp_enqueue_scriptsフックの中でwp_enqueue_style()/wp_enqueue_script()で読み込み、テンプレートに直書きしない - ハンドル名には接頭辞を付け、依存関係とバージョン(
filemtime()が便利)を指定する - 子テーマと親テーマでURL関数が違う。
get_theme_file_uri()・get_stylesheet_directory_uri()・get_template_directory_uri()を区別する - WordPress 6.3 以降は第5引数の配列で
in_footerとstrategy(defer/async)を指定できる - 値の受け渡しは
wp_add_inline_script()とwp_json_encode()、管理画面はadmin_enqueue_scriptsで画面を絞る - 読み込まれないときは、ソース→404→キャッシュ→コンソール→他プラグインの順に確認する