View Script機能を利用して、任意のJavaScriptを実行するWordPressカスタムブロックを作る
Stripe ElementsやGoogle Analyticsなど、Webサイト上でJavaScriptを実行する必要がある場合、WordPressのカスタムブロックを使用してJavaScriptを実行する方法を紹介しています。viewScriptを追加し、JavaScriptファイルを指定してカスタムブロックに追加します。ビルドを行い、ブロックをサイトに追加すると、JavaScriptが実行されます。さらに、DOMの操作やデータの受け渡しも行うことができます。このカスタムブロックは、エディターや保存時に加えて、表示する際の処理にも設定できる便利な機能です。
目次
Stripe Elementsを利用した決済フォームやGoogle Analyticsをはじめとするトラッキング系サービスなど、Webサイト上で任意のJavaScriptを実行する必要のある連携やカスタマイズは珍しいものではありません。とはいえ運営者が自由自在に任意のJavaScriptコードをサイトに追加できる状態も、XSSなどのリスクが高まるため、望ましくありません。そこでWordPressのカスタムブロックを作成し、「このJavaScriptを実行するブロック」を用意する方法を紹介します。
View Scriptをカスタムブロックに追加する方法
View ScriptはWordPressのカスタムブロックで、サイトの表示側で実行するJavaScriptを追加できる仕組みです。src/block.json
にviewScript
を追加し、配列で読み込ませたいファイルを指定しましょう。ファイルのパスは、block.json
から見て相対的なパスで指定します。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
...
"viewScript": ["file:./view.js"]
}
src/block.json
にfile:./view.js
を指定してた場合、実行コードはsrc/view.js
として配置します。この中には通常のJavaScriptコードを追加しましょう。
/* eslint-disable no-console */
console.log( 'Hello World! (from create-block-example-wp-stripe block)' );
/* eslint-enable no-console */
alert("test")
この状態でビルドを実行し、ブロックをサイトに追加すると、そのブロックを含む記事ページにアクセスした時に、JavaScriptが実行されます。
ViewScriptでDOMを操作する
ブロックの設定などをもとに、DOMをViewScriptで操作してみました。src/save.js
を変更して、要素にIDを設定してみましょう。
export default function save() {
return (
<p { ...useBlockProps.save()} id="view-script-target">
{ 'Example Wp Stripe – hello from the saved content!' }
</p>
);
}
src/view.js
側で設定したIDを利用して、テキストを書き換えてみます。
const element = document.getElementById("view-script-target");
element.innerText = "Overwitten!"
ブロックのテキストではなく、src/view.js
で設定したテキストが表示されました。
ブロックの値をViewScriptに渡す
src/save.js
で保存したデータをView Scriptに渡す部分も試してみました。この手のデータの渡し方は、script
タグにJSON.stringify
したデータを入れることだと思いますので、それで組んでみましょう。
export default function save() {
return (
<>
<p { ...useBlockProps.save()} id="view-script-target">
{ 'Example Wp Stripe – hello from the saved content!' }
</p>
<script>
const test = {JSON.stringify(useBlockProps.save())};
console.log(test);
</script>
</>
);
}
ブロックを配置してみると、ブロックの値がconsoleに出力されていることがわかります。
src/view.js
でもデータがとれました。ただしTypeScriptでは型エラーになりますので、as
などを使う必要がありそうです。
// @ts-ignore
console.log(test)
注意点としては、const
やlet
を使っている場合、複数のブロックを配置するとエラーが発生します。
block.json
で複数ブロックの利用を禁止するか、この実装方法をやめるか、それとも変数名をブロックごとにユニークにするか、、どれかを選ぶ必要がありそうです。
"supports": {
"multiple": false
},
触ってみて
エディター・保存時に加えて、表示する際の処理についても設定できるのは便利そうですね。