テクニック

Shopify会員ログインで表示を変える|顧客タグでの出し分け実装ガイド

この記事の対象: Shopifyで卸価格や会員限定商品を扱いたい事業者・制作担当者
読了時間: 約14分

Shopifyで「ログインした人だけに卸価格を見せたい」「会員ランクごとに表示を変えたい」という要望は、BtoB寄りのストアでほぼ必ず出てきます。Shopifyの標準機能だけで済むのか、アプリが要るのか、テーマ改修に踏み込むべきなのか。この判断を間違えると、月額が積み上がるか、逆に運用が回らなくなるかのどちらかに着地します。

この記事では、Shopifyの会員ログインと顧客タグを使った出し分けの実装を具体的なコードで示しながら、「どこまでアプリなしでできて、どこから別の手段が要るのか」の線引きを整理します。実装コードはDawnベースのテーマでそのまま試せる形にしています。


Shopifyの会員向け出し分けは「顧客タグ」が土台になる

なぜ顧客タグなのか

Shopifyの顧客レコードには、標準でタグを付けられます。管理画面の顧客詳細からも付けられますし、APIやShopify Flowからも付けられます。このタグがLiquidからcustomer.tagsとして読めるため、テーマ側で「このタグを持っている人だけ○○を表示する」という分岐が書けます。

顧客メタフィールドを使う方法もありますが、最初に選ぶなら顧客タグをおすすめします。理由は3つあります。

比較軸 顧客タグ 顧客メタフィールド
管理画面での付け外し 顧客詳細画面から直接入力できる 定義を先に作る必要があり、画面も1段深い
一括操作 顧客一覧から複数選択してまとめて付与できる 一括での付け外しがやりにくい
セグメント絞り込み 顧客セグメントの条件に直接使える 条件に使えるが表現がやや複雑
構造化されたデータ 向かない(文字列の集合) 有効期限や取引条件など型付きデータを持てる

「卸会員かどうか」「会員ランクがどれか」のような集合の判定はタグ、「与信枠はいくらか」「契約更新日はいつか」のような値の保持はメタフィールド。この使い分けで大半のケースは整理できます。

なお、両方を併用する構成も普通にあります。ログイン時の表示分岐はタグで速く判定し、画面に出す取引条件の中身(締め日、支払サイト、担当者名)はメタフィールドから引く。判定と内容を分けておくと、条件が増えたときにLiquidの分岐を増やさずに済みます。

タグの命名規則を先に決める

実装より先に決めておくべきなのが命名規則です。ここを曖昧にしたまま運用が始まると、卸と卸売とwholesaleが混在して、Liquid側の判定が次々に漏れ始めます。

推奨する形は「接頭辞つきの英小文字」です。

tier:wholesale      卸会員
tier:vip            VIP会員
access:preorder     先行予約の閲覧権
status:suspended    取引停止中

接頭辞を付けておくと、Liquid側で「tier: で始まるタグ」だけを拾う処理が書けます。日本語タグも動きますが、管理画面で入力するときの表記ゆれ(全角半角、送り仮名)が事故のもとになるので、表示用のラベルはテーマ側で英小文字から日本語に変換する形を取ってください。

あわせて決めておきたいのが、接頭辞の種類を増やしすぎないことです。tier:(ランク)、access:(閲覧権)、status:(取引状態)の3系統に収めておくと、後からタグ一覧を見たときに用途が判別できます。案件ごとにgroup:やarea:を足したくなりますが、それはメタフィールドか顧客セグメントで表現できないかを先に検討してください。


Liquidで顧客タグを判定する実装

基本形:タグの有無で分岐する

もっとも単純な形はこれです。customerオブジェクトはログインしていないときにnilになるため、先に存在チェックを入れるのが要点です。

{%- if customer and customer.tags contains 'tier:wholesale' -%}
  <p class="ts-wholesale-note">卸価格が適用されています。</p>
{%- endif -%}

customer.tags contains 'tier:wholesale' は配列に対する完全一致の判定です。文字列に対するcontainsとは挙動が違い、tier:wholesale-jpのような別タグを誤って拾うことはありません。ここはShopify Liquidの分かりやすい部分です。

ただし大文字小文字は区別されます。管理画面でTier:Wholesaleと入力されていたら一致しません。運用で防ぎきれないと判断したら、正規化してから比較します。

{%- liquid
  assign is_wholesale = false
  for tag in customer.tags
    assign normalized = tag | downcase | strip
    if normalized == 'tier:wholesale'
      assign is_wholesale = true
      break
    endif
  endfor
-%}

{%- if is_wholesale -%}
  <!-- 卸会員向けの表示 -->
{%- endif -%}

breakを入れているのは、一致した時点でループを抜けるためです。タグが数十個付く運用では効いてきます。

もう一段簡潔に書くなら、タグ配列を一度連結してから判定する形もあります。

{%- liquid
  assign tags_lower = customer.tags | join(',') | downcase
  assign is_wholesale = false
  if tags_lower contains 'tier:wholesale'
    assign is_wholesale = true
  endif
-%}

ただしこちらは文字列としての部分一致になるため、tier:wholesale-jpのようなタグも拾ってしまいます。前方一致で困らない命名にしてあるか、カンマを含めて,tier:wholesale,の形で比較するか、どちらかの手当てが要ります。本記事では読みやすさを優先してjoin版を使いますが、タグ名が似通う運用では配列ループ版を選んでください。

スニペットに切り出して使い回す

判定を各所に散らすと、条件を変えたいときに全ファイルを探し回ることになります。判定用のスニペットを1本作って、そこだけを正とする形にしてください。

snippets/ts-customer-tier.liquid を作ります。

{%- comment -%}
  顧客ランク判定
  呼び出し: {% render 'ts-customer-tier' %}
  出力: ts_tier(wholesale / vip / member / guest のいずれか)
{%- endcomment -%}

{%- liquid
  assign ts_tier = 'guest'

  if customer
    assign ts_tier = 'member'
    assign tags_lower = customer.tags | join(',') | downcase

    if tags_lower contains 'tier:vip'
      assign ts_tier = 'vip'
    elsif tags_lower contains 'tier:wholesale'
      assign ts_tier = 'wholesale'
    endif
  endif
-%}

判定の順序に意味があります。VIPと卸の両方のタグが付いた顧客は上位のvipに倒れます。両方を持ち得る運用なら、どちらを優先するかを先に決めてからこの順序を書いてください。「後から足したランクをelsifの末尾に付ける」を続けると、優先順位が実装順で決まってしまいます。

呼び出す側はこうなります。

{%- render 'ts-customer-tier' -%}

ここでつまずきやすい点があります。renderで作った変数は、呼び出し元のテンプレートには渡りません。Shopifyのrenderはスコープが隔離されているためで、includeの時代とは挙動が違います。

判定結果を呼び出し元で使いたい場合は、次のどちらかを選びます。

  1. スニペット側に表示まで含めて書き、呼び出し元はrenderするだけにする
  2. 判定ロジックをsnippets/ではなくテンプレートの先頭に置き、同一スコープ内で使う

実務では1を選ぶことが多いです。「価格ブロック」「限定バッジ」「卸向け注記」のように、出し分けたい単位ごとにスニペットを作り、その中で判定から表示までを完結させます。呼び出し側のテンプレートが汚れず、Dawnのアップデートに追従しやすくなります。

テーマ改修をアップデートに耐える形で進める考え方は、こちらで詳しく整理しています。

商品ページで価格を出し分ける

卸価格の表示は、商品のメタフィールドに卸価格を持たせて、タグ判定で切り替えるのが素直な形です。

まず商品メタフィールドを定義します(管理画面 → 設定 → カスタムデータ → 商品)。

項目 値
名前空間とキー custom.wholesale_price
タイプ 金額(Money)

snippets/ts-price-block.liquid を作ります。

{%- comment -%}
  価格表示(卸会員は卸価格)
  呼び出し: {% render 'ts-price-block', product: product %}
{%- endcomment -%}

{%- liquid
  assign tags_lower = ''
  if customer
    assign tags_lower = customer.tags | join(',') | downcase
  endif

  assign is_wholesale = false
  if tags_lower contains 'tier:wholesale'
    assign is_wholesale = true
  endif

  assign wholesale = product.metafields.custom.wholesale_price
-%}

{%- if is_wholesale and wholesale != blank -%}
  <div class="ts-price ts-price--wholesale">
    <span class="ts-price__label">卸価格</span>
    <span class="ts-price__amount">{{ wholesale | money }}</span>
    <span class="ts-price__retail">(通常 {{ product.price | money }})</span>
  </div>
{%- else -%}
  <div class="ts-price">
    <span class="ts-price__amount">{{ product.price | money }}</span>
  </div>
{%- endif -%}

wholesale != blank のチェックを入れているのは、卸価格が未入力の商品で表示が崩れるのを防ぐためです。卸会員向けの価格表を作る作業は商品数ぶん発生するので、「タグは付いているが商品側の準備が終わっていない」期間が必ず生まれます。その間は通常価格にフォールバックさせておくのが安全です。

なお、メタフィールドの型を「金額(Money)」にした場合、{{ wholesale | money }}がそのまま通ります。型を「テキスト」や「小数」で作ってしまうと通貨記号の付き方が変わるので、定義の段階で型を合わせておいてください。

ここで必ず理解しておくべき制約があります。

このコードは表示を変えているだけで、実際の決済金額は変わりません。 カートに入れた時点で適用されるのは、あくまでバリアントの本来の価格です。表示上は卸価格なのに決済は通常価格、という最悪の状態になります。

表示と決済を一致させる3つの方法

決済金額まで変えるには、別の仕組みが要ります。選択肢は実質3つです。

卸価格を決済に反映させる3つの経路
自動割引 × 顧客セグメントタグ条件のセグメントに割引を自動適用する
卸専用のカタログプランによっては価格表を分けられる
B2B向けアプリ顧客別価格を専用に管理する

もっとも導入が軽いのは1番目です。管理画面の割引から自動割引を作り、適用条件を「特定の顧客セグメント」に限定します。セグメントの条件式にcustomer_tags CONTAINS 'tier:wholesale'を書けば、タグを持つ顧客だけに割引が自動で乗ります。

ただしこの方法には割り切りが要ります。

  • 割引は率か額で効くため、商品ごとに個別の卸価格を設定することはできない
  • 他の割引コードとの併用ルールを設計しないと、想定外の重ね掛けが起きる
  • カート・チェックアウトの表示は「割引が適用された」という形になり、「これが卸価格です」という見え方にはならない

「全商品一律で20%引き」のような単純な卸条件ならこれで足ります。「商品ごとに個別の卸単価がある」場合は、この方法では成立しません。そこからがアプリまたは上位プランの領域です。

2番目の「卸専用のカタログ」は、Shopifyの上位プランで使えるB2B機能を指します。会社(Company)という単位で取引先を管理し、取引先ごとに価格表と支払条件を割り当てる仕組みです。顧客タグでの出し分けとは設計思想そのものが違い、こちらを選ぶ場合はテーマ側の分岐も併せて見直すことになります。自社の契約プランで使えるかどうかを先に確認してから設計に入ってください。

3番目のアプリは、既存プランのまま顧客別価格を実現したい場合の選択肢です。判断材料は後述します。


ログインしていない人にどう見せるか

「隠す」だけでは足りない

出し分けの実装で抜けがちなのが、未ログイン状態の設計です。{% if customer %}で囲って消すだけだと、ユーザーからは「そのページに何も無い」ようにしか見えません。卸取引をしたい見込み客が来ても、そこから先へ進む導線がない状態です。

未ログインには3つの状態があります。それぞれに見せるものが違います。

訪問者の状態と、見せるべきもの

未ログイン(アカウントなし)

  • 卸取引の案内
  • 取引申込フォームへの導線
  • 通常価格は見せる判断もあり

ログイン済み・タグなし

  • 「審査中です」等の状態表示
  • 一般会員としての価格

ログイン済み・タグあり

  • 卸価格・限定商品
  • 専用の注文単位やロット表示

特に見落とされるのが2番目の「ログイン済み・タグなし」です。申し込みはしたが審査が通っていない人がここに入ります。何も出さないと「ログインしたのに何も変わらない、壊れているのでは」という問い合わせに直結します。

3状態を書き分けるとこうなります。

{%- liquid
  assign tags_lower = ''
  if customer
    assign tags_lower = customer.tags | join(',') | downcase
  endif
-%}

{%- if customer == nil -%}

  <div class="ts-gate">
    <p class="ts-gate__lead">卸価格は取引アカウントをお持ちの方のみご覧いただけます。</p>
    <a class="button" href="{{ routes.account_login_url }}">ログイン</a>
    <a class="link" href="/pages/wholesale-apply">取引のお申し込み</a>
  </div>

{%- elsif tags_lower contains 'tier:wholesale' -%}

  {%- render 'ts-price-block', product: product -%}

{%- else -%}

  <div class="ts-gate ts-gate--pending">
    <p>卸価格の閲覧には審査が必要です。お申し込み状況は担当よりご連絡いたします。</p>
  </div>

{%- endif -%}

routes.account_login_urlを直接書いているのは、多言語ストアでパスが変わっても追従させるためです。/account/loginとベタ書きすると、言語別URLを使った瞬間に壊れます。同じ理屈で、アカウント関連のリンクはroutes.account_url・routes.account_register_url・routes.account_logout_urlをそれぞれ使ってください。ここをベタ書きで通してしまうと、多言語対応や顧客アカウントの切り替えのたびに全ファイルを探し直すことになります。

ログイン後に元のページへ戻す

ログイン導線でもう1つ必要なのが、戻り先の指定です。商品ページから「ログイン」を押して、ログイン後にアカウントトップへ飛ばされると、ユーザーは自分で商品ページを探し直すことになります。

<a href="{{ routes.account_login_url }}?return_url={{ request.path | url_encode }}">
  ログインして卸価格を見る
</a>

return_urlはShopifyのアカウントログインが受け取るパラメータです。同一ドメイン内のパスしか受け付けません(外部URLを渡しても無視されます)。仕様上の安全側の挙動なので、ここは素直に従います。

なお、Shopifyの顧客アカウントには従来型(classic)と新しい顧客アカウント(customer accounts)の2系統があり、ログイン画面の見た目やカスタマイズできる範囲が違います。どちらを使っているかで、ログイン周りのテーマ改修の可否が変わります。 新しい顧客アカウントはメールアドレスへのワンタイムコードでログインする方式で、ログイン画面自体はShopify側がホストします。テーマのLiquidでログインフォームを作り込む改修は、こちらでは基本的に効きません。設定 → 顧客アカウントで現在の設定を確認してから設計に入ってください。

ここは見積の前提が変わる箇所です。「ログイン画面に会社のロゴと卸取引の案内を入れたい」という要望が、従来型なら通常のテーマ改修、新しい顧客アカウントなら別の手段(あるいは実現不可)に分かれます。要望を聞いた段階でどちらの設定かを確認してください。

検索・コレクションからの漏れを塞ぐ

商品ページで隠しても、コレクション一覧・検索結果・サイトマップ・JSON API からは見えたままになります。ここが会員限定商品の実装でもっとも事故が起きる箇所です。

{%- comment -%} コレクション一覧側でも同じ判定を通す {%- endcomment -%}
{%- liquid
  assign tags_lower = ''
  if customer
    assign tags_lower = customer.tags | join(',') | downcase
  endif
-%}

{%- for product in collection.products -%}
  {%- liquid
    assign members_only = false
    if product.tags contains 'members-only'
      assign members_only = true
    endif
  -%}

  {%- if members_only and tags_lower contains 'tier:wholesale' == false -%}
    {%- continue -%}
  {%- endif -%}

  {%- render 'card-product', card_product: product -%}
{%- endfor -%}

除外を入れると、ページネーションの件数表示がずれます。Shopifyが「◯件中◯件を表示」と出す数は除外前の件数なので、1ページに並ぶカードの数が設定値より少なくなります。件数が少ないうちは気になりませんが、会員限定商品がまとまった数あるコレクションでは、空に近いページが生まれます。この場合は、そもそも会員限定商品を別コレクションに分け、コレクション自体の表示を出し分けるほうが素直です。

ただし、これはあくまで表示上の除外です。 商品URLを直接叩けばページは開きますし、/products/xxx.jsonを叩けば商品データは返ります。Liquidの分岐は「見えにくくする」ことはできても、「アクセスできなくする」ことはできません。

本当に非公開にしたいものは、次のいずれかで扱ってください。

  • 商品を非公開にし、卸専用の別の販売チャネル/別ストアで扱う
  • 卸専用のカタログ機能を持つプランを使う
  • アクセス制御を持つB2Bアプリを使う

「Liquidで隠せば見えない」という前提で設計すると、後から発覚して作り直しになります。設計段階でここを確認してください。 発注する側が確認すべき問いは1つです。「この商品は、URLを知っている人に見られても困らないか」。困るなら、テーマ改修の範囲では解けません。


アプリを使うべき境界はどこか

アプリを使うべき境界はどこか

アプリなしで足りるケース

ここまでのコードで対応できるのは、次の条件をすべて満たすケースです。

  • 卸条件が全商品一律の率または額で表現できる
  • 会員ランクが数種類で、増減が頻繁でない
  • 限定商品は「見えにくければいい」程度で、厳格な非公開は不要
  • 取引申込の審査が手作業で回る件数(月に数件〜数十件)
  • 決済は通常のチェックアウトで問題ない(掛売り・請求書払いが不要)

これに当てはまるなら、アプリを入れずにテーマ改修で完結させたほうが、月額もページ速度も有利です。判定スニペット数本と、割引の自動適用設定だけで済みます。

アプリまたは上位プランが必要になるケース

逆に、次のどれか1つでも当てはまったら、テーマ改修だけでは成立しません。

要件 なぜテーマ改修で足りないか
商品ごとに個別の卸単価がある 割引は率・額でしか効かず、Liquidは表示しか変えられない
最低注文数量・ロット単位の制約 カートのバリデーションがテーマ側では担保しきれない
掛売り・請求書払い チェックアウトの決済手段そのものの話
取引先ごとに見える商品が完全に違う 表示除外では守れない
見積依頼→承認→注文のフロー 注文前の状態を持つ仕組みが必要
顧客が数千件、タグ付けが自動化必須 運用側の仕組みが要る

この線引きの考え方そのものは、Shopify全般に共通します。

アプリを選ぶときに見る箇所

B2B・卸価格まわりのアプリは選択肢が多く、機能一覧を見比べても差が分かりません。実際に見るべきなのは次の4点です。

最終更新日。Shopifyは年に複数回、テーマとチェックアウトの仕様を変えます。更新が1年以上止まっているアプリは、次の変更で壊れる可能性を抱えています。

自社テーマとの相性。多くのアプリが「Dawnを含む主要テーマに対応」と書きますが、実際にはテーマの価格表示部分にスクリプトを挿し込む形で動くものが多く、カスタマイズ済みのテーマでは素直に入らないことがあります。導入前に、開発用テーマのコピーで試してください。

解約時に何が残るか。アプリを外した後、テーマに挿し込まれたコードや、商品・顧客に付けられたメタフィールドが残るケースがあります。残骸はページ速度とメンテナンス性の両方を削ります。導入時に「アンインストール時の挙動」をドキュメントで確認しておくと、後々効きます。

管理画面を触る人の負担。Shopifyの標準画面と、アプリ独自の画面の二箇所を行き来する運用になります。日々の受注処理をする人が「どちらで何をするのか」を覚えられるか。ここは機能比較表には出てこない、しかし継続率に直結する部分です。

料金については、無料枠のあるものから月額数十ドル規模のものまで幅があります。最新の料金は各アプリのページで確認してください。 為替と改定で頻繁に変わるため、記事や比較サイトの金額は当てになりません。

複数アプリを入れた場合の積み上がりと、その抑え方はこちらで扱っています。

改修費用の考え方

「会員で表示を変えたい」という要望の見積は、機能名ではなくどこまで踏み込むかで決まります。制作会社に相談する前に、次の段階のどれを求めているかを整理しておくと、見積の幅が一気に縮まります。

段階 実装の中身 工数が動く要因
表示だけ変える 判定スニペット+価格ブロック 出し分ける箇所の数(商品ページのみか、一覧・検索・カートまでか)
決済金額も変える 自動割引の設計+セグメント運用 割引の併用ルール、卸条件の複雑さ
限定商品を守る 別チャネル/別ストア/B2B機能 ストア構成そのものの変更を伴うか
運用まで組む Flowでの自動タグ付け、申込フォーム連携 連携先の数と審査フローの分岐

段階が1つ上がるごとに、触るファイルではなく設計の範囲が広がります。最初の段階と最後の段階では、同じ「会員向け表示」でも工数の桁が変わります。相見積を取るときは、この表のどの段階を依頼しているのかを各社に同じ文面で伝えてください。段階の認識がずれたまま金額だけを並べると、安い見積が一番狭い範囲を指しているだけ、ということが起こります。


運用で効いてくる設計

タグ付けを誰がやるか決める

実装が終わっても、タグが付かなければ何も起きません。運用設計で決めるべきは3つです。

顧客タグ運用の3つの決めごと
付与のきっかけ申込フォーム受領/審査完了/初回注文など
付与する人管理画面から手動か、Shopify Flowで自動か
外すきっかけ取引停止・休眠時に誰が外すか

この3つのうち、抜けやすいのは3番目です。付ける手順は決まっているのに、外す手順が決まっていないストアをよく見ます。取引が終わった相手に卸価格が見え続ける状態は、実害が出るまで誰も気づきません。

件数が増えてきたら、Shopify Flowでの自動化を検討します。「タグAが付いたらタグBを外す」「注文完了時に条件を見てタグを付ける」といった処理が組めます。合わせて、四半期に一度タグの一覧を棚卸しする運用を決めておくと安全です。顧客セグメントでtier:wholesaleを持つ顧客を絞り込み、現在の取引先リストと突き合わせる。10分で終わる作業ですが、これをやっていないストアでは、退会・取引終了した相手のタグがそのまま残っています。

表示速度への影響を見ておく

顧客タグの判定自体はLiquidの処理なのでサーバー側で完結し、フロントエンドの負荷にはなりません。ここは安心してよい部分です。

一方で、キャッシュとの相性は意識してください。Shopifyのページはログイン状態によって内容が変わるため、出し分けを入れた時点でそのページはユーザーごとに異なるHTMLになります。CDNのキャッシュが効きにくくなる領域が生まれるということです。

商品ページ全体を出し分けるより、変わる部分だけを小さく切り出す設計にしておくと影響が最小化されます。価格ブロックだけ、バッジだけ、注記だけ。この粒度を守ってください。

アプリ経由で出し分けを実装した場合は話が別で、スクリプトの読み込みがそのまま表示速度に乗ります。

コーポレートサイトと兼用する場合の考え方

卸取引を扱うストアは、一般消費者向けの顔と、取引先向けの顔を同じドメインで持つことになります。会社概要・事業内容・採用といったコーポレートの情報も同じサイトに載せたい、という要望とセットで出てくることが多い構成です。

Shopifyをコーポレートサイトと兼用する設計については、判断材料をこちらにまとめています。顧客タグでの出し分けは、この構成と組み合わせたときに効いてきます。

運用している側から見た実感

受託でShopifyを組むだけでなく、自社でもDawnベースのストアを運用していると、出し分けまわりで気づくことがあります。

一番大きいのは、「表示が変わること」を運用側が把握しきれなくなるという問題です。ログイン状態とタグの組み合わせで見え方が変わるため、管理画面を見ているだけでは実際のお客様の画面が分かりません。修正を入れたときに、どの状態の人にどう見えるかを毎回確認する手間が発生します。

対策として、社内用のテスト顧客アカウントを状態ごとに用意しておくことをおすすめします。「未ログイン用にシークレットウィンドウ」「タグなし会員」「卸会員」「VIP会員」。4つのブラウザプロファイルを分けておけば、修正のたびに全パターンを数分で確認できます。この準備をしておくかどうかで、リリース後の事故の量が変わります。

確認する画面も決めておいてください。商品ページ、コレクション一覧、検索結果、カート、そしてログイン直後のアカウントページ。この5枚を各状態で見る、と決めておけば、抜けやすい「コレクション一覧だけ古い判定が残っていた」が見つかります。出し分けのバグは、本番で会員に見られるまで誰も気づかない種類のものなので、確認の型を先に作っておくことが効きます。

もう1つは、タグを増やしすぎないことです。要望が出るたびにタグを足していくと、Liquidの分岐が組み合わせ爆発を起こします。ランクは3つまで、それ以上必要になったらメタフィールドか別の仕組みを検討する、という上限を最初に決めておくと後が楽になります。


実装前に確認すべきチェックリスト

実装前に確認すべきチェックリスト

着手前に、次の項目を埋めてください。埋まらない項目があるなら、そこが未決定事項です。

確認項目 決めておくこと
会員ランクの数 何段階か。今後増える見込みはあるか
卸価格の決まり方 全商品一律か、商品ごとに個別か
決済への反映 表示だけでよいか、決済金額も変えるか
限定商品の扱い 見えにくくすればよいか、完全非公開が必要か
未ログイン時の表示 通常価格を見せるか、価格ごと隠すか
タグ付けの担当 誰がいつ付けて、誰がいつ外すか
顧客アカウントの種別 従来型か、新しい顧客アカウントか
想定顧客数 手作業で回るか、自動化が必須か
出し分ける画面の範囲 商品ページのみか、一覧・検索・カートまでか
既存アプリとの重なり 価格表示に触るアプリが既に入っていないか

特に「決済への反映」は、見積前に必ず確認する項目です。「会員価格を出したい」という一言が、表示だけの改修なのか、決済フローまで含む構築なのかで、工数が一桁変わります。ここを曖昧にしたまま進めると、後半で必ず揉めます。

最後の「既存アプリとの重なり」も見落とされがちです。定期購入アプリやポイントアプリが既に価格表示に手を入れている場合、そこへ独自の価格ブロックを重ねると、どちらが最終的に表示されるかが読めなくなります。着手前に、テーマのコードから価格表示まわりに挿し込まれているスクリプトを確認してください。


よくある質問

顧客タグはお客様から見えますか?

管理画面上のタグは顧客本人には表示されません。ただし、テーマ側でタグを使って表示を出し分けている場合、そのタグの存在は表示内容から推測できる状態になります。取引条件など、知られると差し障りのある情報をタグ名に含めないでください。

Liquidで隠した商品は検索エンジンにも出なくなりますか?

なりません。Liquidの分岐は表示を変えるだけで、商品自体は公開状態のままです。URLを直接開けば見えますし、.jsonを付ければ商品データも取得できます。検索エンジンからも除外したいなら、商品を非公開にするか、販売チャネルを分ける必要があります。

会員ランクごとに送料を変えることはできますか?

Shopifyの配送プロファイルは商品単位の設定なので、顧客タグでの直接の出し分けはできません。実務では「特定の顧客セグメントに送料無料の自動割引を適用する」形で近い挙動を作ります。配送設定の全体像はShopifyの配送設定完全ガイドで整理しています。

顧客タグの数に上限はありますか?

1顧客あたりに付けられるタグ数には上限があり、実運用で到達することは稀ですが、自動でタグを付与し続ける設計にしていると積み上がります。用途の終わったタグを外す処理をセットで組んでおいてください。最新の上限値はShopifyのドキュメントで確認できます。

新しい顧客アカウントでも顧客タグでの出し分けは使えますか?

使えます。customer.tagsはテーマのLiquidから読める情報なので、顧客アカウントの種別に関わらず商品ページやコレクション一覧での出し分けは動きます。違いが出るのはログイン画面そのものとアカウントページ側で、新しい顧客アカウントではShopifyがホストする画面になるため、テーマ側で作り込める範囲が狭くなります。

アプリを入れた後でテーマ改修に戻せますか?

戻せますが、コストがかかります。アプリが挿し込んだコードの除去、商品・顧客データの移行、動作していた機能の再実装が必要になるためです。「とりあえずアプリで始めて、後で自前に切り替える」という進め方は、切り替えのタイミングを最初に決めていないと実行されません。


まとめ

Shopifyの会員ログインに応じた出し分けは、顧客タグとLiquidの分岐で土台を作るのが基本です。判定用のスニペットを1本に集約し、命名規則を先に決め、未ログイン・タグなし・タグありの3状態を書き分ける。ここまではアプリなしで実装できます。

境界は明確です。表示を変えるだけならテーマ改修で足りる。決済金額・注文制約・アクセス制御に踏み込むなら、別の仕組みが要る。 この線を見積前に確認しておくことが、後の揉めごとを防ぎます。

そして実装より難しいのは運用です。誰がタグを付け、誰が外すか。状態ごとの表示をどう確認するか。ここを設計に含めておくと、公開後に効いてきます。