[Wordpress]6.4以降でscriptタグにnonceやdeferを設定する方法[6.4+]
Wordpress 6.4になってから以前まで簡易的に使用していたdefer, asyncの指定や、nonceの指定が効かなくなったことによるメモ。
1. 以前まで使用していたコード
以前までは、生成されたscriptタグに対して置き換えを行うことによって、属性を追加することが可能であった。
- 置き換えの例
function add_defer($tag, $handle) {
return str_replace("type='text/javascript'", "type='text/javascript' defer", $tag);
}
add_filter('script_loader_tag', 'add_defer', 10, 2);
こうすることによって、wp_enqueue_scriptsなどで生成されるjsタグに対して、deferなどの新しい属性を追加できたが、この方法がWordpress 6.4で破壊され、動かなくなった。
2. 新しいコード
5.7で追加されたwp_script_attributesとwp_inline_script_attributesを使用して、nonce属性を。
deferはwp_enqueue_scriptの段階で付与するように変更しよう。
- defer, async
wp_enqueue_script(
'example', // scriptタグのID
'/scripts/sample.js', // パス
array(), // 依存関係のあるscript ID(これより前に読み込むjsを配列で)
false, // バージョン表記をする場合はバージョンを
array(
'strategy' => 'defer', // deferやasyncの情報
'in_footer' => false // フッターに書くか、falseならhead内
)
);
第5引数の部分に設定することが可能になった。
なお、省略した場合はtrueと同等となり、deferなどは付与されずフッターに記載されるようになる。
また、配列指定する場合は、in_footerのみ、などではエラーになり動かない。
単にhead内に入れたい場合は、第5引数をfalseにする。
- nonce
// 外部参照の場合
function org_script_attributes($attr){
if($attr['type'] !== 'text/javascript') {
return $attr;
}
$attr['source'] = 'external'; // 外部参照の明記、なくても問題ない
$attr['nonce'] = '123'; // nonceは安全なワンタイムトークンを発行
return $attr;
}
// インラインスクリプトの場合
function org_inline_script_attributes($attr){
if($attr['type'] !== 'text/javascript') {
return $attr;
}
$attr['source'] = 'inline'; // インラインの明記、なくても問題ない
$attr['nonce'] = '123'; // nonceは安全なワンタイムトークンを発行
return $attr;
}
add_filter('wp_script_attributes', 'org_script_attributes');
add_filter('wp_inline_script_attributes', 'org_inline_script_attributes');
// CSPの例
"script-src 'self' 'nonce-123';"
外部参照(ファイルからの読み込み)とインライン参照、両方記載しないと、片方だけnonceが入って、片方は入らないという事故につながるので、両方とも合わせて記載しておこう。
6.4にアップグレードしたら色々とエラーが吐かれてちょっと焦ったのでメモとして。
3. 参考にさせてもらった記事
https://developer.wordpress.org/reference/hooks/wp_inline_script_attributes/
https://make.wordpress.org/core/2023/10/17/script-loading-changes-in-wordpress-6-4/