> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# しきい値到達時に無料ギフトを自動追加する

> カート合計がしきい値を超えたときに無料ギフトを追加し、合計が下回ったら削除するCart SDKのユースケース。

カート合計を監視し、無料ギフトをそれと同期させます。購入者が購入金額のしきい値を超えたらギフトを追加し、下回ったら削除します。

<Note>
  ティア、マーケットごとのルール、プログレスバーを備えたマーチャント設定可能なバージョンには、コード不要の[Rewards](/ja/aftersell/cart/rewards-block)ブロックを使用してください。これは、あなたのルールがブロックでは表現できない場合のためのものです。
</Note>

<div id="the-snippet">
  ## スニペット
</div>

**Cart settings → Custom script → Initialization**に貼り付け、2つの定数を設定してください。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const FREE_GIFT_VARIANT_ID = 1234567890; // the gift product's variant id
const THRESHOLD_CENTS = 5000;            // $50.00, since totals are in cents

function reconcileGift(state) {
  const gift = state.items.find((line) => line.variantId === FREE_GIFT_VARIANT_ID);
  const qualifies = state.totalPrice >= THRESHOLD_CENTS;

  if (qualifies && !gift) {
    window.aftersell.cart.actions.addItem(FREE_GIFT_VARIANT_ID, 1);
  } else if (!qualifies && gift) {
    window.aftersell.cart.actions.removeItem(gift.key);
  }
}

window.aftersell.cart.events.on('cart_loaded', reconcileGift);
window.aftersell.cart.events.on('cart_updated', reconcileGift);
```

<div id="how-it-works">
  ## 仕組み
</div>

\*\*`reconcileGift`\*\*はカートが*あるべき*状態を記述し、そこに到達するために最大1つの変更を行います。

* 条件を満たしていてギフトがない → [`addItem`](/ja/aftersell/cart/sdk-actions#additemvariantid-quantity)で追加します。
* 条件を満たしておらずギフトがある → [`removeItem`](/ja/aftersell/cart/sdk-actions#removeitemkey)でラインの`key`を指定して削除します。
* それ以外 → 何もしません。

これは[`cart_loaded`](/ja/aftersell/cart/sdk-events#cart_loaded)（ページ読み込み時にすでに条件を満たしているカートにギフトが追加される）と[`cart_updated`](/ja/aftersell/cart/sdk-events#cart_updated)（その後のすべての変更に反応する）の両方で実行されます。`cart_loaded`は遅れてサブスクライブした場合にも再生されるため、スクリプトがいつ実行されても機能します。

<Warning>
  **`!gift` / `gift`のガードがループを止めています。** ギフトを追加すると`cart_updated`が発火し、`reconcileGift`が再度実行されますが、2回目の実行ではギフトがすでに存在するため何もしません。ガードを外すと無限ループになります。[2つのルール](/ja/aftersell/cart/sdk-events#the-two-rules)を参照してください。
</Warning>

ギフトを追加すると**カート合計が上がる**ため、商品価格に近いしきい値では振動が発生する可能性があることに注意してください。\$0のギフトを追加するのは安全ですが、価格のあるギフトはそれ自体でカートをしきい値以上に押し上げる可能性があります。ギフトは無料にするか、ギフトを除外した合計と比較してください。

<div id="adapting-it">
  ## 応用
</div>

**購入金額の代わりに商品数で判定する：**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.itemCount >= 3;
```

**特定の商品がカートにあるかどうかで判定する：**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.items.some((line) => line.productId === TRIGGER_PRODUCT_ID);
```

**特定の国のみで有効にする。** カート読み込み前から利用可能な[`context`](/ja/aftersell/cart/sdk-overview#context)を読み取ります。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const ELIGIBLE = ['US', 'CA'];

// Only register the handlers for eligible countries.
if (ELIGIBLE.includes(window.aftersell.cart.context.customer_country)) {
  window.aftersell.cart.events.on('cart_loaded', reconcileGift);
  window.aftersell.cart.events.on('cart_updated', reconcileGift);
}
```

**ギフトをしきい値から除外して**、ギフト自身が条件を維持しないようにします。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const subtotalWithoutGift = state.items.reduce(
  (sum, line) => (line.variantId === FREE_GIFT_VARIANT_ID ? sum : sum + line.finalLinePrice),
  0
);
const qualifies = subtotalWithoutGift >= THRESHOLD_CENTS;
```

**ギフトだとわかるようにマークする。** [ライントランスフォーム](/ja/aftersell/cart/sdk-hooks#registerlinetransform)はラインのタイトル、バリエーションタイトル、非表示状態、内部プロパティを変更できるので、ラベルを付け直します。

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.variantId === FREE_GIFT_VARIANT_ID) {
    line.setTitle('Free gift 🎁');
  }
});
```

<Note>
  ライントランスフォームでは**ラインの数量コントロールを非表示にすることはできません** — 使用できるセッターは`setTitle`、`setVariantTitle`、`setHidden`、`setInternalProperties`のみです。購入者がギフトの数量を変更した場合は、代わりに`cart_updated`ハンドラーから修正してください。
</Note>

<div id="where-to-go-next">
  ## 次に読むべきページ
</div>

* **[Rewardsブロック](/ja/aftersell/cart/rewards-block)**：ティア付きのノーコード版。
* **[アクション](/ja/aftersell/cart/sdk-actions)**：`addItem`、`removeItem`など。
* **[イベント](/ja/aftersell/cart/sdk-events)**：ガードが重要な理由。
