Shopify Horizon v4.2.0 アップデート ― RTL言語への対応・カート不具合の修正

Shopify Horizon v4.2.0 アップデート解説 ― RTL対応とカート「戻る」ボタン不具合の修正

Shopify公式テーマ「Horizon」が v4.1.5 から v4.2.0 に進みました。本記事では、コードの差分を読み解きながら、v4.1.5 から v4.2.0 への変更内容と、ストア運営者が押さえておくべきポイントをまとめます。

前回の「v4.1.5 アップデート解説」ではセーフエリア対応を取り上げましたが、今回の目玉はRTL(右から左に書く言語)対応です。加えて、カートの「戻る」ボタン周りの実用的なバグ修正も入っています。

変更サマリー ― 「181ファイル変更」の中身

差分は 181ファイル変更、+1,590行 / −712行。新規・削除ファイルは無く、既存ファイルへの変更のみです。

ストア運営者が気にすべき変更は、大きく次の通りです。

変更 影響範囲 対応の要否
① RTL(右から左に書く言語)対応 アラビア語・ヘブライ語等での多言語展開 該当言語で展開しているストアのみ確認。それ以外は不要(自動で適用)
② カートの「戻る」ボタンで古い内容が表示される不具合の修正 カートドロワー・カートページの表示の正確性 不要(自動で適用)
③ アカウントポップオーバーの表示位置修正 ヘッダーのアカウントアイコン操作時の見た目 不要(自動で適用)
④ 価格フィルターの入力値消失バグ修正 コレクション・検索結果ページの絞り込み操作 不要(自動で適用)

順に解説します。

変更点① ― RTL(右から左に書く言語)対応

今回最大の変更です。公式リリースノートには次のように記載されています。

"This update improves support for right-to-left (RTL) languages. The HTML page's base text direction is now set to match the shopper's requested language, correcting text order and alignment."

実装を確認すると、layout/theme.liquid の<html>タグに、ストアの言語設定に応じて自動的に書字方向を切り替える属性が追加されていました。

<html
  lang="{{ request.locale.iso_code }}"
  dir="{{ request.locale.direction | default: 'ltr' }}"  // 新規追加
>

あわせて、これまでleft/rightで固定的に書かれていたCSSの多くが、「論理プロパティ」(inset-inline-start/inset-inline-end 等、書字方向に応じて左右が自動反転する指定)に置き換えられています。

/* sections/header.liquid(言語セレクターの矢印アイコン位置)*/
- right: var(--margin-xs);
+ inset-inline-end: var(--margin-xs);

日本語・英語など左から右に書く言語のストアでは、見た目の変化はありません。アラビア語・ヘブライ語などRTL言語でストアを多言語展開している場合に効いてくる変更です。価格・SKU・割引コード・ギフトカードコードの表示順序や、横スクロールのフェード表示・ポップオーバーの位置なども、RTL環境向けに個別に修正されています。

変更点② ― カートの「戻る」ボタンで古い内容が表示される不具合の修正

ブラウザの「戻る」ボタンで前のページに戻ると、カートドロワー・カートページにすでに削除・変更したはずの古い商品行が表示され続ける不具合が修正されました。

実装を見ると、原因と対策がコード内コメントに詳しく書かれています。ブラウザには「戻る」操作時にページを再構築せず、直前の状態をそのまま復元するbfcache(back/forward cache)という仕組みがありますが、カートの中身が変わった後に戻ると、DOMは変更前の凍結された状態のまま復元されてしまいます。assets/component-cart-items.js に、この復元を検知してカートセクションを再描画する処理が新設されました。

特に興味深いのは、Chromeだけの特殊事情への対応です。コード内コメントには次のように明記されています。

「Chromeは、Shopifyアカウントでのサインイン用iframe(shopify-account > shop-loginのシャドウルート内)を含むページではbfcacheを拒否する。商品ページはすべてこのiframeを持つため、そこでの「戻る」はHTTPディスクキャッシュからページを再構築する形になり、persistedはfalseになるが、凍結されたカートの表示はそのまま出てしまう」

そのため、pageshowイベントのpersistedフラグだけでなく、Navigation APIのback_forward判定も組み合わせる2経路のチェックで実装されています。Safari・Firefoxは通常のbfcache復元で、Chromeはこのナビゲーション種別判定で捕捉する、という書き分けです。

変更点③ ― アカウントポップオーバーの表示位置修正

ヘッダーのアカウントアイコンをクリックした際に開くポップオーバー(Shopify純正の<shopify-account> Web Component)が、ヘッダー下部ではなく、アカウントボタンの直下から開くよう修正されました。

// assets/header.js に新設
document.addEventListener('open', (event) => {
  // shopify-account 要素の open イベントを検知
  const bottom = Math.max(0, Math.round(event.target.getBoundingClientRect().bottom));
  event.target.style.setProperty('--account-dialog-top', `${bottom}px`);
}, true);

💡 このコードは、公式テーマ「Dawn」が v16.0.0 で顧客アカウントをShopify純正の<shopify-account> Web Componentへ刷新した際に使われているものと一字一句同じ実装です。この部品が、Shopify公式テーマ間で共有されるようになっていることがうかがえます。

変更点④ ― 価格フィルターの入力値消失バグ修正

コレクション・検索結果ページの価格フィルターで、上限・下限の入力欄を行き来すると、入力途中の値が消えてしまう不具合が修正されました。

対策の中身は、前回のv4.1.5解説記事で取り上げた「カート数量入力の値が消える不具合」とまったく同じ仕組みです。data-skip-value-updateというマーカー属性を、入力中の要素に一時的に付与し、裏側の再描画(morph)がその値を上書きしないようにする、というパターンがassets/facets.jsの価格フィルターにも展開されています。

// assets/facets.js に新設(PriceFacetComponent)
#onFocusIn = (event) => {
  event.target.setAttribute('data-skip-value-update', 'true');
};
#onFocusOut = (event) => {
  event.target.removeAttribute('data-skip-value-update');
};

v4.1.5で導入された堅牢化パターンが、今回別の入力欄(価格フィルター)に横展開された形です。同じ設計思想がテーマ内で再利用されていることが分かります。

その他の変更

変更 概要
Quick AddのJS読み込み条件化 snippets/scripts.liquid。quick-add.jsの読み込みが、{% if settings.quick_add or settings.mobile_quick_add %}で囲われ、Quick Add機能を使っていないストアでの無駄な読み込みを削減
Catalogリンクのエラー表示修正 商品画像が無い場合にメニューのCatalogリンクがLiquidエラーとして表示されていたのを、テキストリンクとして表示するよう修正
フィルタードロワーの余白修正 フィルターを何も適用していない状態で、「見る」ボタン横に不要な余白が空いていたのを修正
モバイル2列グリッドの画像最適化 コレクション・検索結果のモバイル2列グリッドで、商品カード画像により小さいサイズを配信するよう変更(表示速度の改善)
ヘッダー言語セレクターの配色修正 透過ヘッダー使用時、言語セレクターの矢印アイコンだけ上段の文字色のまま残っていたのを、透過ヘッダーの文字色に追従するよう修正
ポップアップリンク内動画のSafari再生修正 blocks/popup-link.liquid。ポップアップ内にアップロードした動画がSafariで再生されなかったのを、開閉に連動して再生・停止するよう修正
スウォッチ行の初期表示幅修正 角丸スタイルの商品カードで、レイアウト初期化前にスウォッチ行がカード幅を広げてしまう不具合を修正

アップデート手順

安全カスタマイズ記事で構築したupstream/horizonブランチ運用を使っている場合、管理画面の対象テーマから「コードを編集 → ダウンロード」で最新版のファイル一式を取得し、このブランチにまるごと反映してupstream/v4.2.0・horizon-v4.2.0のタグを打って管理します。

⚠️ Shopify公式のGitHub公開ミラー(github.com/Shopify/horizon)は、実際にストアへ配信される内容と乖離することがあります(過去のv4.1.4アップデートで実際に発生)。実店舗からのテーマエクスポートを正として検証することをお勧めします。

まとめ

v4.1.5 → v4.2.0 はアップデート推奨です。目玉のRTL対応は日本語ストアには直接関係しませんが、カートの「戻る」ボタン問題は、ブラウザバックで買い物を続ける購入者が一定数いることを考えると、地味ながら実用的な修正と言えます。

  • 多言語(RTL言語)でストアを展開している場合は、配色・レイアウトの左右反転が正しく機能しているか確認するとよいでしょう。
  • v4.1.5で導入された「入力中の値を保護する」仕組みが、今回価格フィルターにも展開されました。同じ設計パターンが横展開されていく様子は、テーマの成熟度を測る良い指標になります。
  • アカウントポップオーバーの位置修正コードがDawn 16.0.0と一字一句同じだった点から、<shopify-account>周りの実装がテーマ間で共有されつつあることがうかがえます。

ファイル構成がバージョンごとに変わりうるテーマだからこそ、「どこを触ったか」を常に把握できるGit管理(upstream/horizonブランチでのオリジナル追跡)が、こうした地道なアップデートでも効いてきます。