Shopify テーマエディタ内でセクションファイル内のJSを動かすことに関するメモ

窓辺

ShopifyのテーマエディタでJavascriptを動かす際にスムーズに進められなかったのでメモとして。

前提

  • Shopifyのテーマエディタでセクションファイル内の自作のJSを動かす

できるだけテーマ内の他のファイルを触らずに対応する方がメリットがあると考えているので、theme.liquidでJSを読み込んだり直接書いたりする方法は除外しています。

メモ

テーマエディタ用イベントは以下を参照のこと。

window.addEventListener


// テーマエディタでも以下は動作するが、初回表示時点でしか実行されず、セクション設定で変更した際などには実行されない
window.addEventListener('DOMContentLoaded', (event) => {
  console.log('fire');
});

↓

// 下記のようにテーマエディタ用のイベントも使う必要がある
window.addEventListener('DOMContentLoaded', (event) => {
  console.log('fire');
});
document.addEventListener('shopify:section:load', (event) => {
  console.log('fire');
});

要素の操作1


// 下記のように要素を取得してなんらかの操作を行う場合、テーマエディタ用イベントの発生時に動作しない
const bar = () => {
  const obj = document.getElementById('foo');
  const p = document.createElement('p');
  obj.appendChild(p);
};
window.addEventListener('DOMContentLoaded', (event) => {
  bar();
});
document.addEventListener('shopify:section:load', (event) => {
  bar();
});

↓

// 下記のようにテーマエディタ用のイベントごとに要素を取得し直して用いると動作する
const bar = (obj) => {
  const p = document.createElement('p');
  obj.appendChild(p);
};
window.addEventListener('DOMContentLoaded', (event) => {
  const obj = document.getElementById('foo');
  bar(obj);
});
document.addEventListener('shopify:section:load', (event) => {
  const obj = document.getElementById('foo');
  bar(obj);
});

要素の操作2


// テーマエディタのセクションやブロック設定に連動してJSの結果を変更したい場合、以下のような書き方では変更が反映されない。
const foo = {{ section.settings.num }}

// 下記のようにdata属性でHTML内に出力してから、テーマエディタ用のイベントごとに要素を取得し、そこから値を取得して用いると変化を反映させられる
<div data-num="{{ section.settings.num }}">

// data属性以外でも、以下のようにJSONとして出力可能であれば、textContentを使って中身を取得してからJSON.parseを使う方法なども考えられる
<script type="application/json">
 {{ array | json }}
</script>

scriptタグ


// 以下のどちらを使ってもテーマエディタ用のイベントは動作する。
<script>
</script>

{%- javascript -%}
{%- endjavascript -%}

{%- javascript -%}には以下のような特徴もあります。

  • const num = {{ num }};のようにliquidを書いても展開されない(多分)
  • {% if foo %}{% endif %}のようなタグで囲めない
  • ファイル内で1回しか記載できない

セクションファイルのみでは実現不可の動作?

調べた範囲では以下のような状態でした。

  • 初回のセクション追加時では、テーマエディタ用イベントを使ってもJSが動作しない
  • 一度保存すると動作する
  • theme.liquidなどセクションファイル外に記載しないと実行できない

例えばJSで値を取得しHTMLとして出力するセクションの場合、初回のセクション追加時点ではJSが一切動作しないのでHTMLが出力されません。
セクションファイルに直接書いてもJSを読み込ませても動作しません。

保存すれば表示されるためストアフロント側には全く影響ありませんが、テーマエディタで事前に確認できない点は問題になり得ます。
調査試作の結果、現時点での結論としては対応不可能でした。

Dawnテーマで類似の動作の仕組みを調べた限りでは、theme.liquidで読みこませているJS内で実行されているようでした。
セクション設定変更時のリロード時にも上記JSは実行されるので、テーマエディタ用イベントを使わずとも動かせるようです。

You need to use these tags only if your section or app block is meant to be installed on multiple themes or stores. Otherwise, you should include the JavaScript that your section needs in your theme’s assets directory. Each section or app block can have only one {% javascript %} tag.

上記のようにも書かれており、セクションファイル内にJavascriptを書くのはあまり想定していないのかもしれません。
インストール前提という点でアプリが該当するのはわかりますが、セクションを複数ストアにという状況を理解しかねている状態です。

結び

単に調査不足というだけもしれませんが、セクションファイル内にJSをまとめようとするとうまくいきません。
セクションファイル以外でJSを実行させれば問題はでないはずです。

3人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄