BLOGShopifyカスタマイズ事例8:商品タグ連動型「関連記事」の表示

POST DATE:2025/06/06
Shopifyカスタマイズ事例8:商品タグ連動型「関連記事」の表示
ECの利益向上に繋がるShopifyカスタマイズ事例8
弊社ではShopifyでの制作をはじめ、様々なECサイトの制作のご依頼をいただいています。
特に、現在はECサイトの売上をUPしつつ効率的な運用を行いたい、月商を1,000万円以上の規模に成長させたい、月商億円規模のサイトを安全にシステム移管したい等、「利益を上げる知識」と「システム構築の知識」を総合的に持つことで解決できるご要望を、ワンストップで実現することを得意としています。
その現場の中で行ってきたカスタマイズ事例について、解説します。
事例8:商品タグ連動型「関連記事」の表示
カスタマイズの背景
商品ページに訪れたユーザーは、スペック情報だけでなく「使い方の例」や「開発背景などのストーリー性」を求める傾向が強まっています。弊社にご相談いただいたサイトのご商品も、商品の設置方法や設置事例が必要な商品だったのですが、すべての情報を商品詳細だけでは伝えるのが難しい商品でした。
そのため、商品詳細ページに、関連したブログ記事を自動表示できると、商品に関係する記事コンテンツの表示・更新・管理が簡単になるのですが、Shopifyのデフォルトでは、そのような機能が存在していませんでした。
そこで、商品に設定したタグと同じタグを持つブログ記事を自動抽出し、商品ページ下部に「関連記事」として表示するカスタマイズを実施しました。
カスタマイズ前の課題
- 説明や利用例が必要な商品であり、商品の購入率が想定よりも低かった
- 商品ページの購入前後にブログ記事を閲覧しているケースが多い傾向だったが、商品詳細側からの動線は無かった
- 商品が複数あるので、管理・更新を効率的に行いたい
- 関連記事アプリの月額コストの増加を抑制したい
カスタマイズでの要件・解決案
- 商品タグと記事タグを比較して、完全自動で関連記事を抽出
- 表示件数・並び順・カラム数を、ノーコードで変更可能に
- セクションで設置・更新できるように設定し、EC担当者でも簡単に調整できるように
- ページ速度に影響しないよう、遅延読み込み & 軽量構成を維持
- Liquidでの開発・設置により、月額コストの増加を回避
実装方法
全体Liquidコード
このコードを、セクションのliquidコードとして用意し、商品詳細ページに追加セクションとして組み込むことで、商品タグに応じた関連記事の自動表示を実現しています。
{% liquid assign blog_handle = section.settings.blog if blogs[blog_handle] == nil assign related_posts = [] else assign limit_count = section.settings.article_limit | default: 3 assign sort_order = section.settings.sort_order assign posts = blogs[blog_handle].articles assign related_posts = [] for article in posts # 共通タグがあれば収集 for t in article.tags if product.tags contains t assign related_posts = related_posts | push: article break endif endfor endfor # 並び替え if sort_order == 'random' assign related_posts = related_posts | shuffle elsif sort_order == 'newest' assign related_posts = related_posts | sort: 'published_at' | reverse else assign related_posts = related_posts endif # 表示数でカット assign related_posts = related_posts | slice: 0, limit_count endif %} {% if related_posts.size > 0 %} <section id="RelatedBlogPosts-{{ section.id }}" class="related-blog-posts"> <style> #RelatedBlogPosts-{{ section.id }}{ --col-desk: {{ section.settings.columns_desktop }}; --col-mob: {{ section.settings.columns_mobile }}; } #RelatedBlogPosts-{{ section.id }} .articles-grid{ display:grid; gap:1.5rem; grid-template-columns:repeat(var(--col-mob),1fr); } @media(min-width:768px){ #RelatedBlogPosts-{{ section.id }} .articles-grid{ grid-template-columns:repeat(var(--col-desk),1fr); } } #RelatedBlogPosts-{{ section.id }} .post_card a{ display:block;text-decoration:none;color:inherit;height:100%; } #RelatedBlogPosts-{{ section.id }} .post_card img{ width:100%;height:auto;display:block; } #RelatedBlogPosts-{{ section.id }} .post_meta{ font-size:.85rem;color:#777; } </style> <div class="articles-grid"> {% for a in related_posts %} <article class="post_card"> {% if a.image %} <a href="{{ a.url }}"><img src="{{ a.image | image_url: width:1200 }}" alt="{{ a.image.alt | default: a.title | escape }}" width="{{ a.image.width }}" height="{{ a.image.height }}" loading="lazy" ></a> {% endif %} <h3 class="post_title"><a href="{{ a.url }}">{{ a.title }}</a></h3> {% if section.settings.show_date or section.settings.show_author %} <p class="post_meta"> {% if section.settings.show_date %} <time datetime="{{ a.published_at | date: '%Y-%m-%d' }}"> {{ a.published_at | date: '%Y/%m/%d' }} </time> {% endif %} {% if section.settings.show_author %} {% if section.settings.show_date %} | {% endif %} {{ a.author }} {% endif %} </p> {% endif %} </article> {% endfor %} </div> </section> {% endif %} {% schema %} { "name": "商品の関連記事", "settings": [ { "type": "blog", "id": "blog", "label": "対象ブログ", "default": "news" }, { "type": "select", "id": "sort_order", "label": "並び順", "options": [ { "value": "newest", "label": "新着順" }, { "value": "random", "label": "ランダム" } ], "default": "newest" }, { "type": "range", "id": "article_limit", "label": "記事表示数", "min": 1, "max": 12, "step": 1, "default": 3 }, { "type": "range", "id": "columns_desktop", "label": "PC表示カラム数", "min": 1, "max": 4, "step": 1, "default": 3 }, { "type": "range", "id": "columns_mobile", "label": "スマホ表示カラム数", "min": 1, "max": 4, "step": 1, "default": 1 }, { "type": "checkbox", "id": "show_date", "label": "投稿日を表示", "default": true }, { "type": "checkbox", "id": "show_author", "label": "投稿者を表示", "default": false } ], "presets": [ { "name": "商品の関連記事" } ] } {% endschema %}
コード解説
1. セクション設定&初期化
Liquid でブログハンドルや表示数を取得し、関連記事配列を用意します。
assign blog_handle = section.settings.blog if blogs[blog_handle] == nil assign related_posts = [] # 対象ブログが存在しなければ空で終了 else assign limit_count = section.settings.article_limit | default: 3 assign sort_order = section.settings.sort_order assign posts = blogs[blog_handle].articles assign related_posts = []
ポイント:
・section.settings.*
は テーマエディタ側で変更できる値 を自動反映する便利な仕組みです。エンジニアがコードを触らなくても、EC 担当者が記事件数や並び順を管理画面で変更できます。
2. 商品タグと記事タグを突き合わせ
二重ループでタグを比較し、マッチした記事を表示対象として配列化します。
for article in posts # 共通タグがあれば収集 for t in article.tags if product.tags contains t assign related_posts = related_posts | push: article break endif endfor endfor
ポイント:
・商品側のタグは product.tags
が配列で返るため、contains
で高速照合できます。
・break
を入れることで 1 記事につき最初の一致でループ終了。不要なタグ比較をカットしパフォーマンスを確保しています。
3. ソート & 上限件数の制御
新着順かランダムかをセレクトボックスで切替。
最後に slice
で表示件数を制限します。
if sort_order == 'random' assign related_posts = related_posts | shuffle elsif sort_order == 'newest' assign related_posts = related_posts | sort: 'published_at' | reverse endif assign related_posts = related_posts | slice: 0, limit_count endif
ポイント:
・shuffle
は Liquid 標準の 配列シャッフル フィルターです。毎回順序が変わるのでランダム表示が可能です。
・sort: 'published_at' | reverse
は実質、新着順です。昇順に並んだあと reverse
で反転しています。
4. フロント出力(HTML + CSS)
グリッド列数をCSSで可変化し、PC/スマートフォンでの表示変更に対応します。
{% if related_posts.size > 0 %} <section id="RelatedBlogPosts-{{ section.id }}" class="related-blog-posts"> <style> #RelatedBlogPosts-{{ section.id }}{ --col-desk: {{ section.settings.columns_desktop }}; --col-mob: {{ section.settings.columns_mobile }}; } #RelatedBlogPosts-{{ section.id }} .articles-grid{ display:grid; gap:1.5rem; grid-template-columns:repeat(var(--col-mob),1fr); } @media(min-width:768px){ #RelatedBlogPosts-{{ section.id }} .articles-grid{ grid-template-columns:repeat(var(--col-desk),1fr); } } </style> <div class="articles-grid"> {% for a in related_posts %} <article class="post_card"> {% if a.image %} <a href="{{ a.url }}"><img src="{{ a.image | image_url: width:1200 }}" alt="{{ a.image.alt | default: a.title | escape }}" width="{{ a.image.width }}" height="{{ a.image.height }}" loading="lazy"></a> {% endif %} <h3 class="post_title"><a href="{{ a.url }}">{{ a.title }}</a></h3> {% if section.settings.show_date or section.settings.show_author %} <p class="post_meta"> {% if section.settings.show_date %} <time datetime="{{ a.published_at | date: '%Y-%m-%d' }}"> {{ a.published_at | date: '%Y/%m/%d' }} </time> {% endif %} {% if section.settings.show_author %} {% if section.settings.show_date %} | {% endif %} {{ a.author }} {% endif %} </p> {% endif %} </article> {% endfor %} </div> </section> {% endif %}
ポイント:
・画像に loading="lazy"
を付け、ビューポート下の画像は スクロール時に後読み込み。表示速度の改善に寄与します。
・カード全体を <a>…</a>
で囲まず、画像とタイトルそれぞれをリンク化→アクセシビリティ面でスクリーンリーダー対策となります。
5. セクション設定(schema)
すべてのオプションは管理画面から変更できます。
{% schema %} { "name": "商品の関連記事", "settings": [ { "type": "blog", "id": "blog", "label": "対象ブログ", "default": "news" }, { "type": "select", "id": "sort_order", "label": "並び順", "options": [ { "value": "newest", "label": "新着順" }, { "value": "random", "label": "ランダム" } ], "default": "newest" }, { "type": "range", "id": "article_limit", "label": "記事表示数", "min": 1, "max": 12, "step": 1, "default": 3 }, { "type": "range", "id": "columns_desktop", "label": "PC表示カラム数", "min": 1, "max": 4, "step": 1, "default": 3 }, { "type": "range", "id": "columns_mobile", "label": "スマホ表示カラム数", "min": 1, "max": 4, "step": 1, "default": 1 }, { "type": "checkbox", "id": "show_date", "label": "投稿日を表示", "default": true }, { "type": "checkbox", "id": "show_author", "label": "投稿者を表示", "default": false } ], "presets": [ { "name": "商品の関連記事" } ] } {% endschema %}
ポイント:
・各設定値とオプション値を、管理画面側から選択できるようにすることで、ノーコード運用を実現しています。
全体のポイント
今回のカスタマイズは、Shopifyのタグ機能を活用し、商品ページとブログを関連記事として結びつけることで、商品ページからの回遊率や商品購入率の向上を意図した関連記事を、自動で表示することが可能です。
適切な記事を用意することで、購入時に説明や事例が必要な商品に、改善効果を期待することができます。
結果
実装したサイトでは、商品の購入検討材料となる関連記事の存在で、対象商品の購入件数が向上する結果となりました。また回遊率向上の効果から、単価向上にも前向きな数字が出ており、ユーザーのエンゲージメントとしても良い結果となりました。
商品の特性を選ぶ施策ではありますが、商品購入の検討材料が必要な商品については、推奨の施策となります。(記事側からも該当商品に戻る仕掛けを作ることで、より効果があります)
Shopifyでは、セクションの活用で柔軟なカスタマイズが可能ですので、ぜひ自社ECサイトの向上に繋がる実装を試してみてください。
お気軽にお問い合わせください
弊社ではECをスタートされる方から、大規模ECの安全なリニューアル、個別のカスタマイズ実装まで幅広く対応可能です。
ご相談がございましたら、お気軽にご連絡ください。