StoreCRMのお気に入り機能に、「お気に入り一覧ページのデザイン編集(上級者モード)」機能が追加されました。表示に使われるLiquid(テンプレート)をテキストとして編集することで、商品カードの並び・余白・ボタン配置・文言などを、ストアの世界観や既存テーマに合わせて自由に調整できます。
コード変更はこのページ内で完結し、反映結果を確認しながら微調整できるため、「テーマだと限界があるけどフル開発は重い」というケースでも、手早く理想の見た目に近づけられます。
[上級者モード(Liquid)で設定]について

StoreCRMの[設定]>[お気に入り設定]より、お気に入り一覧画面の編集が可能です。デフォルトでは[かんたん設定モード]が選択されている状態ですが、[上級者モード(Liquid)で設定]を選択することで、Liquidテンプレートを編集してのお気に入り一覧画面のカスタマイズが可能となります。
カスタマイズ方法

Liquidテンプレートを任意のテキストに編集して、保存を押下することでお気に入り一覧画面のデザインが反映されます。[プレビュー]より、現在のLiquidテンプレートに入力された状態での、お気に入り一覧画面のプレビューを確認することができます。
デフォルト状態

デフォルト状態では、[かんたん設定モード]と同様のお気に入り一覧画面となっています。Liquidテンプレートを編集して動作に問題があった場合は、[デフォルトにリセット]を押下することでデフォルトのLiquidテンプレートのテキストが入力された状態へ復帰することができます。
お気に入り一覧画面のテンプレート例3選
ここでは、コピーアンドペーストですぐに利用できる、お気に入り一覧画面のLiquidテンプレートの例を紹介します。
シンプルなブロック型のデザイン

こちらは、デフォルトのリスト型のデザインとは異なり、ブロック型のデザインとなります。またフラットなデザインとすることで、どのShopifyテンプレートでも活用しやすいデザインとしています。Liquidテンプレートのコードは下記の通りになります。
{% assign locale_code = request.locale.iso_code | default: locale | default: 'ja' %}
{% if locale_code == 'ja' %}
{% assign list_title = 'お気に入り' %}
{% assign non_item_text = '現在お気に入り中の商品はありません' %}
{% assign item_unit_text = 'アイテム' %}
{% assign cta_text = '商品を見る' %}
{% else %}
{% assign list_title = 'Favourites' %}
{% assign non_item_text = 'There are currently no favorited items.' %}
{% assign item_unit_text = 'items' %}
{% assign cta_text = 'Shop products' %}
{% endif %}
{%- comment -%}
1回目のループで「有効な」お気に入り数を数える(見出しの “0 アイテム” 表示用)
{%- endcomment -%}
{% assign items_count = 0 %}
{% if item_handles and item_handles.size > 0 %}
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
%}
{% assign items_count = items_count | plus: 1 %}
{% endfor %}
{% endif %}
{% assign has_items = false %}
{% if items_count > 0 %}
{% assign has_items = true %}
{% endif %}
<style>
.storecrm_favs {
max-width: 1200px;
width: 100%;
margin: 24px auto 64px;
padding: 0 16px;
padding-left: 0 !important;
padding-right: 0 !important;
font-family: -apple-system, BlinkMacSystemFont, "Noto Sans JP", "Hiragino Sans", "Yu Gothic", "Segoe UI", Roboto, Arial, sans-serif;
color: #111;
}
.storecrm_favs_header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
margin: 8px 0 12px;
}
.storecrm_favs_title {
font-size: 28px;
font-weight: 700;
letter-spacing: 0.02em;
margin: 0;
line-height: 1.15;
}
.storecrm_favs_count {
font-size: 14px;
font-weight: 600;
color: #555;
margin: 6px 0 0;
}
.storecrm_favs_breadcrumb {
font-size: 12px;
color: #666;
margin: 14px 0 22px;
}
.storecrm_favs_breadcrumb a {
color: inherit;
text-decoration: none;
}
.storecrm_favs_breadcrumb a:hover {
text-decoration: underline;
}
.storecrm_favs_breadcrumb_sep {
display: inline-block;
margin: 0 6px;
color: #999;
}
/* Empty state */
.storecrm_favs_empty {
border-top: 1px solid #eee;
padding-top: 20px;
margin-top: 8px;
color: #333;
}
.storecrm_favs_empty_text {
display: block;
font-size: 14px;
color: #444;
margin-bottom: 16px;
}
.storecrm_favs_cta {
display: inline-block;
padding: 12px 18px;
border: 1px solid #111;
background: #111;
color: #fff;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.03em;
}
.storecrm_favs_cta:hover {
opacity: 0.85;
}
/* Grid cards */
.storecrm_favs_grid {
list-style: none;
padding: 0;
margin: 0;
display: grid;
gap: 18px 18px;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1100px) {
.storecrm_favs_grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 780px) {
.storecrm_favs_grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
.storecrm_favs_grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }
}
.storecrm_favs_card {
position: relative;
border: 1px solid #eee;
background: #fff;
}
.storecrm_favs_card:hover {
border-color: #ddd;
}
.storecrm_favs_media {
display: block;
position: relative;
background: #f6f6f6;
aspect-ratio: 3 / 4; /* 画像比率:アパレルっぽく縦長 */
overflow: hidden;
text-decoration: none;
}
.storecrm_favs_media img {
width: 100%;
height: 100%;
object-fit: cover;
transform: scale(1);
transition: transform 0.25s ease;
display: block;
}
.storecrm_favs_card:hover .storecrm_favs_media img {
transform: scale(1.03);
}
.storecrm_favs_body {
padding: 12px 12px 14px;
}
.storecrm_favs_name {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 13px;
font-weight: 600;
line-height: 1.4;
color: #111;
text-decoration: none;
}
.storecrm_favs_name:hover {
text-decoration: underline;
}
.storecrm_favs_sub {
margin-top: 6px;
font-size: 12px;
color: #666;
line-height: 1.4;
}
.storecrm_favs_price {
margin-top: 10px;
font-size: 13px;
font-weight: 700;
color: #111;
}
.storecrm_favs_badge {
margin-top: 8px;
display: inline-block;
font-size: 11px;
font-weight: 700;
color: #b00020;
border: 1px solid #f0c6cf;
background: #fff5f7;
padding: 4px 8px;
}
/* Actions overlay (右上縦並び) */
.storecrm_favs_actions {
position: absolute;
top: 10px;
right: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.storecrm_favs_action {
width: 36px;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
background: rgba(255,255,255,0.95);
border: 1px solid #e6e6e6;
text-decoration: none;
color: #111;
cursor: pointer;
}
.storecrm_favs_action:hover {
border-color: #cfcfcf;
}
.storecrm_favs_action svg {
width: 18px;
height: 18px;
}
.storecrm_favs_action--remove{
color: #e0002b; /* ハートの赤 */
border-color: #ffd0d9;
background: rgba(255,255,255,0.98);
}
.storecrm_favs_action--remove:hover{
border-color: #ff9fb1;
}
/* 右上ハート:枠なし、SVGだけ */
.storecrm_favs_heart{
display: inline-flex;
align-items: center;
justify-content: center;
border: none !important;
background: transparent !important;
padding: 0 !important;
width: auto !important;
height: auto !important;
color: #e0002b; /* 赤 */
cursor: pointer;
text-decoration: none;
}
.storecrm_favs_heart svg{
width: 22px;
height: 22px;
display: block;
}
/* カートに追加:価格の下のボタン */
.storecrm_favs_addtocart{
display: block;
margin-top: 10px;
padding: 12px 12px;
text-align: center;
background: #111;
color: #fff;
border: 1px solid #111;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.02em;
}
.storecrm_favs_addtocart:hover{
opacity: 0.85;
}
</style>
<div class="storecrm_favs">
<div class="storecrm_favs_header">
<div>
<h1 class="storecrm_favs_title">{{ list_title }}</h1>
<div class="storecrm_favs_count">{{ items_count }} {{ item_unit_text }}</div>
</div>
</div>
<nav class="storecrm_favs_breadcrumb" aria-label="breadcrumb">
<a href="/help/en/{{ routes.root_url }}/">Home</a>
<span class="storecrm_favs_breadcrumb_sep">/</span>
<span aria-current="page">{{ list_title }}</span>
</nav>
<div
id="non_item_text"
class="storecrm_favs_empty"
{% if has_items %}style="display:none;"endif %}
>
<span class="storecrm_favs_empty_text">{{ non_item_text }}</span>
<a class="storecrm_favs_cta" href="/help/en/{{ routes.all_products_collection_url }}/">{{ cta_text }}</a>
</div>
{% if has_items %}
<ul class="storecrm_favs_grid" role="list">
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
assign item_url = variant.url | default: product.url | default: '#'
assign item_title = product.title
if variant.title and variant.title != 'Default Title'
assign item_title = item_title | append: ' - ' | append: variant.title
endif
assign item_available = variant.available
assign item_thumbnail = variant.image | default: product.featured_image
assign product_id = product.id
assign variant_id = variant.id
assign item_handle = product_handle
%}
<li class="storecrm_favs_card storecrm_customlist_id-{{ variant_id }}">
<a class="storecrm_favs_media" href="/help/en/{{ item_url }}/">
{% if item_thumbnail %}
<img src="{{ item_thumbnail | img_url: '800x' }}" alt="{{ item_title | escape }}">
{% endif %}
</a>
<div class="storecrm_favs_actions">
<a
class="storecrm_favs_heart"
href="javascript:void(0);"
aria-label="Remove from favourites"
data-product-id="{{ product_id }}"
data-variant-id="{{ variant_id }}"
>
<svg viewbox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 21s-6.7-4.35-9.33-8.14C.6 9.7 1.5 6.9 3.85 5.6c2.03-1.12 4.3-.6 5.68.95L12 9.1l2.47-2.55c1.38-1.55 3.65-2.07 5.68-.95 2.35 1.3 3.25 4.1 1.18 7.26C18.7 16.65 12 21 12 21z"
fill="currentColor"
/>
</svg>
</a>
</div>
<div class="storecrm_favs_body">
<a class="storecrm_favs_name" href="/help/en/{{ item_url }}/">{{ item_title }}</a>
<div class="storecrm_favs_sub">
{% if variant.title and variant.title != 'Default Title' %}
{{ variant.title }}
{% endif %}
</div>
<div class="storecrm_favs_price">
{{ variant.price | money }}
{% if item_available %}
<a
class="storecrm_favs_addtocart"
href="/help/en/{{ item_url }}/"
data-cart-variant-id="{{ variant_id }}"
data-cart-product-id="{{ product_id }}"
data-cart-product-handle="{{ item_handle }}"
>
カートに追加
</a>
{% endif %}
</div>
{% unless item_available %}
<div class="storecrm_favs_badge">
{% if locale_code == 'ja' %}在庫なし{% else %}Out of stock{% endif %}
</div>
{% endunless %}
</div>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
シンプルなリスト型のデザイン

最初に紹介した、シンプルなブロック型のデザインの雰囲気を踏襲し、リスト型のデザインとしたテンプレートです。Liquidテンプレートのコードは下記の通りになります。
{% assign locale_code = request.locale.iso_code | default: locale | default: 'ja' %}
{% if locale_code == 'ja' %}
{% assign list_title = 'お気に入り' %}
{% assign non_item_text = '現在お気に入り中の商品はありません' %}
{% assign item_unit_text = 'アイテム' %}
{% assign cta_text = '商品を見る' %}
{% else %}
{% assign list_title = 'Favourites' %}
{% assign non_item_text = 'There are currently no favorited items.' %}
{% assign item_unit_text = 'items' %}
{% assign cta_text = 'Shop products' %}
{% endif %}
{%- comment -%}
1回目のループで「有効な」お気に入り数を数える(見出しの “0 アイテム” 表示用)
{%- endcomment -%}
{% assign items_count = 0 %}
{% if item_handles and item_handles.size > 0 %}
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
%}
{% assign items_count = items_count | plus: 1 %}
{% endfor %}
{% endif %}
{% assign has_items = false %}
{% if items_count > 0 %}
{% assign has_items = true %}
{% endif %}
<style>
.storecrm_favs {
max-width: 1200px;
width: 100%;
margin: 24px auto 64px;
padding: 0 16px;
padding-left: 0 !important;
padding-right: 0 !important;
font-family: -apple-system, BlinkMacSystemFont, "Noto Sans JP", "Hiragino Sans", "Yu Gothic", "Segoe UI", Roboto, Arial, sans-serif;
color: #111;
}
.storecrm_favs_header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
margin: 8px 0 12px;
}
.storecrm_favs_title {
font-size: 28px;
font-weight: 700;
letter-spacing: 0.02em;
margin: 0;
line-height: 1.15;
}
.storecrm_favs_count {
font-size: 14px;
font-weight: 600;
color: #555;
margin: 6px 0 0;
}
.storecrm_favs_breadcrumb {
font-size: 12px;
color: #666;
margin: 14px 0 22px;
}
.storecrm_favs_breadcrumb a {
color: inherit;
text-decoration: none;
}
.storecrm_favs_breadcrumb a:hover {
text-decoration: underline;
}
.storecrm_favs_breadcrumb_sep {
display: inline-block;
margin: 0 6px;
color: #999;
}
/* Empty state */
.storecrm_favs_empty {
border-top: 1px solid #eee;
padding-top: 20px;
margin-top: 8px;
color: #333;
}
.storecrm_favs_empty_text {
display: block;
font-size: 14px;
color: #444;
margin-bottom: 16px;
}
.storecrm_favs_cta {
display: inline-block;
padding: 12px 18px;
border: 1px solid #111;
background: #111;
color: #fff;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.03em;
}
.storecrm_favs_cta:hover {
opacity: 0.85;
}
/* === 1カラム:リスト型(左画像・右情報) === */
.storecrm_favs_grid{
list-style: none;
padding: 0;
margin: 0;
display: flex; /* gridをやめて縦並び */
flex-direction: column;
gap: 0; /* 行間はボーダーで区切る想定 */
}
/* 1行 = 1アイテム */
.storecrm_favs_card{
position: relative;
display: flex;
gap: 16px;
align-items: stretch;
border: none; /* カード枠は消して */
border-top: 1px solid #eee; /* 行の区切りだけ */
background: #fff;
padding: 14px 0;
}
.storecrm_favs_card:last-child{
border-bottom: 1px solid #eee;
}
/* 左:画像 */
.storecrm_favs_media{
flex: 0 0 120px; /* サムネ幅 */
width: 120px;
background: #f6f6f6;
aspect-ratio: 3 / 4;
overflow: hidden;
text-decoration: none;
}
@media (max-width: 420px){
.storecrm_favs_media{
flex-basis: 96px;
width: 96px;
}
}
.storecrm_favs_media img{
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.25s ease;
display: block;
}
.storecrm_favs_card:hover .storecrm_favs_media img{
transform: scale(1.03);
}
/* 右:情報(伸びる) */
.storecrm_favs_body{
flex: 1 1 auto;
padding: 0; /* 既存のpaddingをリスト用に無効化 */
display: flex;
flex-direction: column;
min-width: 0;
}
/* 商品名などはそのままトーン維持 */
.storecrm_favs_name{
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 13px;
font-weight: 600;
line-height: 1.4;
color: #111;
text-decoration: none;
padding-right: 34px; /* 右上ハートとかぶらないように */
}
.storecrm_favs_name:hover{ text-decoration: underline; }
.storecrm_favs_sub{
margin-top: 6px;
font-size: 12px;
color: #666;
line-height: 1.4;
}
/* 価格+カートは下に寄せる */
.storecrm_favs_bottom{
margin-top: auto;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.storecrm_favs_price{
margin-top: 10px;
font-size: 13px;
font-weight: 700;
color: #111;
}
/* カートボタン:横並び用に調整(トーンは維持) */
.storecrm_favs_addtocart{
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 14px;
background: #111;
color: #fff;
border: 1px solid #111;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.02em;
white-space: nowrap;
}
.storecrm_favs_addtocart:hover{ opacity: 0.85; }
/* 右上ハート:行レイアウトに合わせて位置調整(枠なしSVGのみ維持) */
.storecrm_favs_actions{
position: absolute;
top: 14px;
right: 0;
}
.storecrm_favs_heart{
display: inline-flex;
align-items: center;
justify-content: center;
border: none !important;
background: transparent !important;
padding: 0 !important;
color: #e0002b;
cursor: pointer;
text-decoration: none;
}
.storecrm_favs_heart svg{
width: 22px;
height: 22px;
display: block;
}
.storecrm_favs_body {
padding: 12px 12px 14px;
}
.storecrm_favs_name {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 13px;
font-weight: 600;
line-height: 1.4;
color: #111;
text-decoration: none;
}
.storecrm_favs_name:hover {
text-decoration: underline;
}
.storecrm_favs_sub {
margin-top: 6px;
font-size: 12px;
color: #666;
line-height: 1.4;
}
.storecrm_favs_price {
margin-top: 10px;
font-size: 13px;
font-weight: 700;
color: #111;
}
.storecrm_favs_badge {
margin-top: 8px;
display: inline-block;
font-size: 11px;
font-weight: 700;
color: #b00020;
border: 1px solid #f0c6cf;
background: #fff5f7;
padding: 4px 8px;
}
/* Actions overlay (右上縦並び) */
.storecrm_favs_actions {
position: absolute;
top: 10px;
right: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.storecrm_favs_action {
width: 36px;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
background: rgba(255,255,255,0.95);
border: 1px solid #e6e6e6;
text-decoration: none;
color: #111;
cursor: pointer;
}
.storecrm_favs_action:hover {
border-color: #cfcfcf;
}
.storecrm_favs_action svg {
width: 18px;
height: 18px;
}
.storecrm_favs_action--remove{
color: #e0002b; /* ハートの赤 */
border-color: #ffd0d9;
background: rgba(255,255,255,0.98);
}
.storecrm_favs_action--remove:hover{
border-color: #ff9fb1;
}
/* 右上ハート:枠なし、SVGだけ */
.storecrm_favs_heart{
display: inline-flex;
align-items: center;
justify-content: center;
border: none !important;
background: transparent !important;
padding: 0 !important;
width: auto !important;
height: auto !important;
color: #e0002b; /* 赤 */
cursor: pointer;
text-decoration: none;
}
.storecrm_favs_heart svg{
width: 22px;
height: 22px;
display: block;
}
/* カートに追加:価格の下のボタン */
.storecrm_favs_addtocart{
display: block;
margin-top: 10px;
padding: 12px 12px;
text-align: center;
background: #111;
color: #fff;
border: 1px solid #111;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.02em;
}
.storecrm_favs_addtocart:hover{
opacity: 0.85;
}
</style>
<div class="storecrm_favs">
<div class="storecrm_favs_header">
<div>
<h1 class="storecrm_favs_title">{{ list_title }}</h1>
<div class="storecrm_favs_count">{{ items_count }} {{ item_unit_text }}</div>
</div>
</div>
<nav class="storecrm_favs_breadcrumb" aria-label="breadcrumb">
<a href="/help/en/{{ routes.root_url }}/">Home</a>
<span class="storecrm_favs_breadcrumb_sep">/</span>
<span aria-current="page">{{ list_title }}</span>
</nav>
<div
id="non_item_text"
class="storecrm_favs_empty"
{% if has_items %}style="display:none;"endif %}
>
<span class="storecrm_favs_empty_text">{{ non_item_text }}</span>
<a class="storecrm_favs_cta" href="/help/en/{{ routes.all_products_collection_url }}/">{{ cta_text }}</a>
</div>
{% if has_items %}
<ul class="storecrm_favs_grid" role="list">
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
assign item_url = variant.url | default: product.url | default: '#'
assign item_title = product.title
if variant.title and variant.title != 'Default Title'
assign item_title = item_title | append: ' - ' | append: variant.title
endif
assign item_available = variant.available
assign item_thumbnail = variant.image | default: product.featured_image
assign product_id = product.id
assign variant_id = variant.id
assign item_handle = product_handle
%}
<li class="storecrm_favs_card storecrm_customlist_id-{{ variant_id }}">
<a class="storecrm_favs_media" href="/help/en/{{ item_url }}/">
{% if item_thumbnail %}
<img src="{{ item_thumbnail | img_url: '800x' }}" alt="{{ item_title | escape }}">
{% endif %}
</a>
<div class="storecrm_favs_actions">
<a
class="storecrm_favs_heart"
href="javascript:void(0);"
aria-label="Remove from favourites"
data-product-id="{{ product_id }}"
data-variant-id="{{ variant_id }}"
>
<svg viewbox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 21s-6.7-4.35-9.33-8.14C.6 9.7 1.5 6.9 3.85 5.6c2.03-1.12 4.3-.6 5.68.95L12 9.1l2.47-2.55c1.38-1.55 3.65-2.07 5.68-.95 2.35 1.3 3.25 4.1 1.18 7.26C18.7 16.65 12 21 12 21z"
fill="currentColor"
/>
</svg>
</a>
</div>
<div class="storecrm_favs_body">
<a class="storecrm_favs_name" href="/help/en/{{ item_url }}/">{{ item_title }}</a>
<div class="storecrm_favs_sub">
{% if variant.title and variant.title != 'Default Title' %}
{{ variant.title }}
{% endif %}
</div>
<div class="storecrm_favs_bottom">
<div class="storecrm_favs_price">
{{ variant.price | money }}
</div>
{% if item_available %}
<a
class="storecrm_favs_addtocart"
href="/help/en/{{ item_url }}/"
data-cart-variant-id="{{ variant_id }}"
data-cart-product-id="{{ product_id }}"
data-cart-product-handle="{{ item_handle }}"
>
カートに追加
</a>
{% endif %}
</div>
{% unless item_available %}
<div class="storecrm_favs_badge">
{% if locale_code == 'ja' %}在庫なし{% else %}Out of stock{% endif %}
</div>
{% endunless %}
</div>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
日本のECサイトによくあるお気に入り一覧画面

リスト型のデザインのまま、日本のECサイトによくあるUIを踏襲したデザインのお気に入り一覧画面のテンプレートになります。できるだけ多くの情報を、わかりやすデザインで記載しているのが特徴です。Liquidテンプレートのコードは下記の通りになります。
{% assign locale_code = request.locale.iso_code | default: locale | default: 'ja' %}
{% if locale_code == 'ja' %}
{% assign list_title = 'お気に入り一覧' %}
{% assign non_item_text = '現在お気に入り中の商品はありません' %}
{% assign item_unit_text = '件' %}
{% assign btn_add_to_cart = 'カートに入れる' %}
{% assign btn_view = '商品ページへ' %}
{% assign btn_remove = 'お気に入り解除' %}
{% else %}
{% assign list_title = 'Your favorites' %}
{% assign non_item_text = 'There are currently no favorited items.' %}
{% assign item_unit_text = 'items' %}
{% assign btn_add_to_cart = 'Add to cart' %}
{% assign btn_view = 'View item' %}
{% assign btn_remove = 'Remove' %}
{% endif %}
{%- comment -%}
有効な(商品が存在し、variant が取れる)お気に入りだけをカウント
{%- endcomment -%}
{% assign items_count = 0 %}
{% if item_handles and item_handles.size > 0 %}
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
%}
{% assign items_count = items_count | plus: 1 %}
{% endfor %}
{% endif %}
{% assign has_items = items_count | times: 1 | greater_than: 0 %}
<style>
/* ===== Japanese EC-ish Favorites ===== */
.fav-wrap{
max-width: 980px;
margin: 24px auto 56px;
padding: 0 16px;
font-family: -apple-system,BlinkMacSystemFont,"Hiragino Kaku Gothic ProN","Hiragino Sans","Noto Sans JP",Meiryo,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
color: #111;
}
.fav-header{
display:flex;
justify-content:space-between;
align-items:flex-end;
gap:16px;
border-bottom:1px solid #e6e6e6;
padding-bottom:12px;
margin-bottom:16px;
}
.fav-title{
margin:0;
font-size:22px;
font-weight:700;
letter-spacing:.02em;
}
.fav-count{
margin-left:10px;
font-size:13px;
font-weight:600;
color:#666;
}
.fav-subactions{
display:flex;
gap:10px;
align-items:center;
font-size:13px;
}
.fav-subactions a{
color:#111;
text-decoration:none;
border-bottom:1px solid #bbb;
}
.fav-subactions a:hover{ opacity:.75; }
.fav-empty{
display:block;
padding:24px 0;
color:#666;
font-size:14px;
}
.fav-list{
display:flex;
flex-direction:column;
gap:12px;
}
.fav-item{
display:grid;
grid-template-columns: 120px 1fr 220px;
gap:14px;
padding:14px;
border:1px solid #e6e6e6;
background:#fff;
}
.fav-thumb a{ display:block; }
.fav-thumb img{
width:120px;
height:120px;
object-fit:cover;
background:#f7f7f7;
}
.fav-info{
min-width:0;
}
.fav-brand{
font-size:12px;
color:#666;
margin:0 0 6px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.fav-name{
margin:0 0 8px;
font-size:14px;
line-height:1.5;
font-weight:600;
word-break:break-word;
}
.fav-name a{
color:#111;
text-decoration:none;
}
.fav-name a:hover{ text-decoration:underline; }
.fav-meta{
display:flex;
flex-wrap:wrap;
gap:8px;
align-items:center;
margin-top:8px;
}
.fav-badge{
display:inline-flex;
align-items:center;
gap:6px;
padding:3px 8px;
border:1px solid #ddd;
font-size:12px;
color:#333;
background:#fafafa;
}
.fav-badge.is-oos{
border-color:#f0c7c7;
background:#fff5f5;
color:#b00020;
}
.fav-price{
margin-top:10px;
display:flex;
align-items:baseline;
gap:10px;
}
.fav-price .price-now{
font-size:18px;
font-weight:800;
}
.fav-price .price-tax{
font-size:11px;
color:#666;
}
.fav-price .price-was{
font-size:12px;
color:#888;
text-decoration:line-through;
}
.fav-actions{
display:flex;
flex-direction:column;
gap:10px;
justify-content:space-between;
align-items:stretch;
}
.fav-actions-top{
display:flex;
flex-direction:column;
gap:8px;
}
.fav-btn{
display:inline-flex;
justify-content:center;
align-items:center;
gap:8px;
height:40px;
padding:0 12px;
border-radius:2px;
font-size:13px;
font-weight:700;
cursor:pointer;
text-decoration:none;
border:1px solid #111;
background:#111;
color:#fff;
transition:opacity .2s, transform .02s;
}
.fav-btn:hover{ opacity:.85; }
.fav-btn:active{ transform:translateY(1px); }
.fav-btn.is-sub{
background:#fff;
color:#111;
border-color:#111;
font-weight:700;
}
.fav-btn.is-disabled{
opacity:.45;
pointer-events:none;
}
.fav-remove{
display:inline-flex;
justify-content:center;
align-items:center;
height:36px;
font-size:12px;
color:#444;
background:#fff;
border:1px solid #ddd;
text-decoration:none;
cursor:pointer;
}
.fav-remove:hover{ background:#fafafa; }
/* SP */
@media (max-width: 768px){
.fav-item{
grid-template-columns: 96px 1fr;
grid-template-areas:
"thumb info"
"actions actions";
}
.fav-thumb{ grid-area:thumb; }
.fav-info{ grid-area:info; }
.fav-actions{ grid-area:actions; }
.fav-thumb img{ width:96px; height:96px; }
.fav-actions-top{ flex-direction:column; }
}
</style>
<div class="fav-wrap">
<div class="fav-header">
<div>
<h1 class="fav-title">
{{ list_title }}
<span class="fav-count">
{{ items_count }} {{ item_unit_text }}
</span>
</h1>
</div>
{%- comment -%}
必要なら「全削除」などのフックをここに(JS側で拾う)
{%- endcomment -%}
<div class="fav-subactions" {% unless has_items %}style="display:none;"endunless %}>
<a href="javascript:void(0);" data-favorites-clear-all>全て削除</a>
</div>
</div>
<span id="non_item_text" class="fav-empty" {% if has_items %}style="display:none;"endif %}>
{{- non_item_text -}}
</span>
{% if has_items %}
<div class="fav-list">
{% for handle in item_handles %}
{% liquid
assign parts = handle | split: '/'
assign product_handle = parts[0]
assign variant_key = parts[1]
assign product = all_products[product_handle]
assign variant = nil
if product != blank and product.variants
for v in product.variants
assign v_id = v.id | append: ''
if v_id == variant_key
assign variant = v
break
endif
endfor
endif
if product == blank or variant == nil
continue
endif
assign item_url = variant.url | default: product.url | default: '#'
assign item_title = product.title
if variant.title and variant.title != 'Default Title'
assign item_title = item_title | append: ' / ' | append: variant.title
endif
assign item_available = variant.available
assign item_thumbnail = variant.image | default: product.featured_image
assign product_id = product.id
assign variant_id = variant.id
assign item_handle = product_handle
assign brand = product.vendor
%}
<div class="fav-item storecrm_customlist_id-{{ variant_id }}">
<div class="fav-thumb">
{% if item_thumbnail %}
<a href="/help/en/{{ item_url }}/">
<img
src="{{ item_thumbnail | img_url: '240x240' }}"
alt="{{ item_title | escape }}"
loading="lazy"
>
</a>
{% endif %}
</div>
<div class="fav-info">
{% if brand != blank %}
<p class="fav-brand">{{ brand }}</p>
{% endif %}
<p class="fav-name">
<a href="/help/en/{{ item_url }}/">{{ item_title }}</a>
</p>
<div class="fav-meta">
{% if item_available %}
<span class="fav-badge">在庫あり</span>
{% else %}
<span class="fav-badge is-oos">在庫切れ</span>
{% endif %}
</div>
<div class="fav-price">
<span class="price-now">
{{ variant.price | money }}
</span>
<span class="price-tax">税込</span>
{% if variant.compare_at_price and variant.compare_at_price > variant.price %}
<span class="price-was">{{ variant.compare_at_price | money }}</span>
{% endif %}
</div>
</div>
<div class="fav-actions">
<div class="fav-actions-top">
{% if item_available %}
<a
class="fav-btn"
href="/help/en/{{ item_url }}/"
data-cart-variant-id="{{ variant_id }}"
data-cart-product-id="{{ product_id }}"
data-cart-product-handle="{{ item_handle }}"
>
{{ btn_add_to_cart }}
</a>
{% else %}
<a class="fav-btn is-disabled" href="javascript:void(0);">
在庫切れ
</a>
{% endif %}
<a class="fav-btn is-sub" href="/help/en/{{ item_url }}/">
{{ btn_view }}
</a>
</div>
<a
class="fav-remove"
href="javascript:void(0);"
data-product-id="{{ product_id }}"
data-variant-id="{{ variant_id }}"
>
{{ btn_remove }}
</a>
</div>
</div>
{% endfor %}
</div>
{% endif %}
</div>