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の安全なリニューアル、個別のカスタマイズ実装まで幅広く対応可能です。
ご相談がございましたら、お気軽にご連絡ください。