私たちが Kestrel と呼ぶメンズグルーミングブランドから、カスタムセクションのプロジェクトの数週間後に2通目のメッセージが届きました。添付はスクリーンショット1枚。あるジュエリーショップの商品ページで、カートに追加ボタンの下にカードが並び、1点購入で1点無料、2点目を選んでくださいと書かれていました。その下に短い質問がひとつ。うちの商品ページにもこれを付けられますか?
Shopify で1つ買うと1つ無料のオファーは、管理画面ですぐに有効にできます。難しいのは、お客様に実際に使ってもらうことです。この事例では、選択機能をどう作ったか、なぜ参考ストアのコードをコピーしなかったか、そして2点目を本当に無料にする Shopify の設定をひとつ紹介します。
この事例について:実際の Shopify プロジェクトをもとに再構成したものです。ブランド名、商品写真、一部の詳細は変更しており、商品画像はイラストです。コードのパターン、問題、解決策は実際に対応したとおりです。

プロジェクト概要
| クライアント | D2C のメンズグルーミングブランド、オランダ(オランダ語ストア、ユーロ) |
| プラットフォーム | Shopify Online Store 2.0、既存のプレミアムテーマをそのまま使用 |
| 範囲 | snippet 1つ、スタイルシート1つ、スクリプト1つ、新しい商品ページブロック1つ、アプリなし |
| 割引 | Shopify 標準の自動割引(X を購入して Y を獲得) |
| 納品方法 | マーチャント自身がテーマのコードエディタで1ファイルずつ導入 |
Shopify 標準の BOGO 割引だけでは足りない理由
Shopify は何年も前から「X を購入して Y を獲得」割引に対応しています。設定しておけば、条件を満たす商品がカートに入った時点で割引が適用されます。問題は「入った時点で」という部分です。お客様はまずオファーの存在を知り、商品ページを離れ、対象商品を探してカートに入れ、戻ってこなければなりません。ほとんどの人はそこまでしません。行動につながらない「1+1 無料」のバナーは、主に「割引が効かなかったのはなぜ?」というメールを生みます。
参考ストアはこれを選択機能で解決していました。対象商品を購入を決める場所にそのまま表示し、タップひとつで選べ、メインボタンが2点をカートに追加に変わります。Kestrel が求めていたのはこの体験でした。
参考を読み、そして脇に置く
マーチャントは参考ストアの CSS、JavaScript、HTML も送ってくれました。丁寧に作られたもので、約400行。ボトムシート、「すべて見る」オーバーレイ、商品写真の背景色の検出、独自のカート追加リクエストまで含まれていました。しかし別のテーマ、別のフォーム、別のカートドロワー向けに書かれたもので、しかも他社のものです。
そこで私たちはそれを「動きの説明」として扱い、コードとしては使いませんでした。何かを書く前に、Kestrel のテーマの商品フォームを読みました。これがプロジェクトで最も価値のある1時間になりました。
発見:テーマはすでに2つの商品を追加できた
テーマの product-form 要素には「よく一緒に購入されている商品」チェックボックスの機能があります。送信時に、フォームに紐づいた要素内のチェック済み input[name="bundles"] をすべて集め、メイン商品と一緒に /cart/add.js へ送ります。カートドロワー、カートページモード、エラーメッセージ、固定のカート追加ボタンもこの要素が処理しています。
つまり、選択機能には独自のカートリクエストがまったく不要でした。各カードには bundles という名前の非表示チェックボックスがあり、選択機能の要素はフォームの id を持ちます。
<bogo-picker form="{{ product_form_id }}">
<label class="bogo-card__btn">
<input type="checkbox" name="bundles" value="{{ variant.id }}" class="sr-only">
<span>Choose</span>
</label>
</bogo-picker>
カードを選ぶとチェックボックスがオンになります。メインボタンを押すと、テーマが1回のリクエストで2つの商品を追加し、独自のカートドロワーを開いて件数を更新します。ほかの商品とまったく同じ動きです。私たちが書いた JavaScript は約100行で、カートに触れる行は1行もありません。

標準機能のように感じさせる細部
- 無料商品は一度に1つだけ。カードを選ぶとほかのカードの選択が外れるので、誤って無料商品を3つ入れることはありません。
- 何が起きるかを伝えるボタン。カードを選ぶと、ボタンの文言が「2点をカートに追加」に変わります。テーマはバリエーション変更時にこの文言をリセットするため、小さな
MutationObserverが元に戻します。 - カード上でバリエーションを選択。複数のバリエーションがある商品にはコンパクトなドロップダウンが表示され、チェックボックスの値もそれに合わせて変わります。
- そろったカード。CSS subgrid でカードがグリッドの行を共有するので、商品名が2行になっても名前、価格、ボタンの位置がそろいます。
- モバイルファースト。スマートフォンでは2.3枚が見え、次のカードが端からのぞきます。PCでは3枚と矢印ボタンが表示されます。
- きれいにリセット。カート追加に成功すると、選択機能はテーマの
cartUpdateイベントを受け取り、選択をクリアします。
このブロックは、ほかの商品ページブロックと同じようにテーマエディタで追加できます。マーチャントは対象商品のコレクションを選ぶか、商品ごとのオファーには商品リストのメタフィールドを使います。「無料」「選ぶ」、ボタンの文言などはすべて設定項目です。表示中の商品と売り切れ商品は自動的に除外されます。
2点目を本当に無料にする
選択機能がするのは、カートに2つの商品を入れることだけです。価格は Shopify の自動割引が処理します。
- 無料で提供できる商品のコレクションを作成します。例:「BOGO 無料」。
- ディスカウントで、方法を自動にしたX を購入して Y を獲得割引を作成します。
- 顧客が購入する商品:すべての有料商品を含むコレクションから最小数量1。
- 顧客が獲得する商品:「BOGO 無料」から数量1、値は無料。
- 注文ごとの最大使用回数を設定するにチェックを入れて1と入力します。そうしないと3点購入で3点無料になります。

Shopify の「顧客が購入する商品」欄には「すべての商品」という選択肢がないため、ここにはコレクションが必要です。条件を「価格が0より大きい」にした自動コレクションなら、常に最新の状態に保たれます。知っておくべき特殊なケースがひとつあります。無料商品がそのコレクションにも含まれていると、「BOGO 無料」から2点買えば1点が無料になります。多くのストアではこれで問題ありません。避けたい場合は、BOGO 商品にタグを付け、コレクションの条件でそのタグを除外してください。

テーマをアップロードせずに導入
Kestrel の公開中テーマには未公開の作業が進行中だったため、新しいテーマバージョンのアップロードはできませんでした。そこで機能をコードエディタ向けの5つの正確な手順として納品しました。新しいファイル3つ(snippet、スタイルシート、スクリプト)と、商品セクションへの小さな追記2つ(render の1行と、スキーマのブロック定義1つ)です。各手順では、どの行を検索し、その上に何を貼り付けるかを明記しました。変更はすべて追加のみなので、次のテーマ更新でも数分の作業で再適用できます。
「BOGO 無料」コレクション用のシンプルなサムネイルも作成し、テーマのどこに表示されても完成した見た目になるようにしました。
BOGO を検討しているストアへのアドバイス
- 選択は、購入を決める場所に置きましょう。お客様が自分で組み立てなければならないオファーは、ほとんどの人に素通りされます。
- コードを書く前にテーマを読みましょう。このプロジェクトで最高の1行は、書かずに済んだ1行です。テーマがすでにバンドルをカートに追加できたからです。
- 価格のロジックは Shopify に任せましょう。標準の自動割引はカート、チェックアウト、すべてのレポートで機能し、テーマに触れずに一時停止できます。
- 注文ごとの使用回数は初日から制限しましょう。
プレゼント選択機能、バンドル作成機能、その他のカスタム商品ページ機能をご希望の場合は、Shopify テーマ開発サービスをご覧いただくか、ストアについてお聞かせください。
よくある質問
Shopify はアプリなしで「1つ買うと1つ無料」に対応していますか?
はい。「X を購入して Y を獲得」の自動割引は Shopify に標準で備わっています。足りないのは商品ページで無料商品を選ぶ仕組みで、それを補うのがこの選択機能です。
私のテーマでも使えますか?
この考え方はどの Online Store 2.0 テーマでも使えます。実装は、テーマの商品フォームがどのようにカートへ追加するかによって変わります。今回はテーマのバンドル機能を再利用しましたが、ほかのテーマでは Cart API への1回のリクエストで2点を追加します。
無料商品にバリエーションがあっても大丈夫ですか?
はい。複数のバリエーションがある商品はカード上に小さなドロップダウンを表示し、選んだバリエーションがカートに追加されます。
お客様に悪用されませんか?
何が無料になるかを決めるのは選択機能ではなく割引です。注文ごとの最大使用回数を1にすれば、1回の注文で無料商品を2つ以上得ることはできません。
商品ごとに違う無料商品を表示できますか?
はい。ブロックは標準でコレクションを読み込み、商品リストのメタフィールドで商品ごとに上書きできます。