> ## 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.

# チェックアウト前に規約への同意を必須にする

> Aftersell Cart に利用規約のチェックボックスを追加し、購入者が同意するまでチェックアウトをブロックする Cart SDK のユースケース。

チェックアウトボタンの下にチェックボックスを追加し、購入者がチェックを入れるまで先に進めないようにします。規約への同意、年齢確認、受注生産の確認などに便利です。

<Warning>
  **`checkout` イベントではチェックアウトをキャンセルできません。** このイベントはブラウザが遷移する直前の通知として発火するため、`false` を返しても `preventDefault` を呼んでも何も起きません。チェックアウトをゲートする唯一の方法は、ボタンが押される*前に*クリックへの反応を止めることであり、このページではその方法を説明します。

  これは UI 上の抑止策であり、法的な保証ではありません。意図を持った購入者は、依然として直接チェックアウトに到達できます。
</Warning>

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

構成要素は 3 つです。

1. チェックアウトボタンの下の**カスタムコードブロック**がチェックボックスをレンダリングします。
2. チェックが外れている間、ブロックは [shadow root](/ja/aftersell/cart/sdk-overview#shadowroot) を通じてカートのチェックアウトボタンとエクスプレス決済ボタンにクラスを追加します。
3. **カスタム CSS** がそのクラスでクリックを無効化します。

<div id="step-1-add-the-checkbox-block">
  ## ステップ 1: チェックボックスブロックを追加する
</div>

Checkout button ブロックの下に[カスタムコードブロック](/ja/aftersell/cart/custom-code-blocks)を追加し、**React component** モードに切り替えて、次を貼り付けます。

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  const [accepted, setAccepted] = useState(false);

  useEffect(() => {
    const root = window.aftersell?.cart?.shadowRoot;
    if (!root) return;

    const targets = root.querySelectorAll(
      '.cart-external-checkout-button, .cart-external-express-buttons'
    );
    targets.forEach((el) => el.classList.toggle('checkout-gated', !accepted));
  }, [accepted, props.cart]);

  return (
    <div style={{ width: '100%', fontSize: '14px', textAlign: 'center' }}>
      <label style={{ display: 'flex', gap: '6px', justifyContent: 'center', alignItems: 'center' }}>
        <input
          type="checkbox"
          checked={accepted}
          onChange={(e) => setAccepted(e.target.checked)}
        />
        <span>
          I accept the{' '}
          <a href="https://yourstore.com/terms" target="_blank" rel="noopener noreferrer">
            Terms &amp; Conditions
          </a>
        </span>
      </label>
      {!accepted && (
        <div style={{ color: '#c00', fontWeight: 600, marginTop: '6px' }}>
          Please accept the terms above to continue.
        </div>
      )}
    </div>
  );
}
```

**Compile** をクリックし、\*\*「Use custom template」\*\*をオンにします。オンにするまでブロックは何もレンダリングしません。

`props.cart` の依存関係が重要です。カートの再レンダリング後にクラスを再適用します。これがないと再レンダリングでクラスが消えてしまいます。

<div id="step-2-add-the-css">
  ## ステップ 2: CSS を追加する
</div>

**Cart settings → Custom CSS** に次を追加します。

```css theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
.checkout-gated {
  pointer-events: none !important;
  opacity: 0.5 !important;
}
```

実際にクリックをブロックするのは `pointer-events: none` です。opacity は購入者に理由を示すためのものです。

<div id="step-3-test-it">
  ## ステップ 3: テストする
</div>

[プレビュー](/ja/aftersell/cart/previewing-carts)で以下を確認します。

* 読み込み時にチェックアウトボタンが薄く表示され、クリックに反応しない。
* チェックを入れると有効になり、外すと再び無効になる。
* エクスプレス決済ボタンもゲートされている。
* チェックが外れている間に商品を追加・削除してもボタンが再有効化されない。

最後の項目がよくある失敗ポイントです。カートの変更後にボタンが勝手に再有効化される場合は、effect が再実行されていません。依存配列に `props.cart` が含まれているか確認してください。

<div id="tracking-who-accepted">
  ## 誰が同意したかを記録する
</div>

チェックボックスはブラウザ内だけの状態であり、注文には届きません。同意を記録するには、カート追加時にすべてのラインへプロパティとして刻印します。

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<input type="hidden" name="properties[_terms_version]" value="2026-01">
```

これをテーマの商品フォームに追加してください。Shopify は `properties[...]` をフォームから直接読み取るため、追加を実行するのが Aftersell であれ、テーマであれ、別のアプリであれ、値は注文に届きます。

`_` で始まるプロパティは購入者向けの表示には現れませんが、Shopify には届くため、注文に表示されます。これが記録するのは*どの*規約バージョンが有効だったかであり、購入者がチェックを入れた事実ではありません。

<div id="things-to-get-right">
  ## 押さえておくべきポイント
</div>

* **`cart-external-*` クラスだけを対象にする。** 対になる `cart-internal-*` はカート自身の内部機構であり、コードから触れるためのハンドルではありません。[カスタム CSS](/ja/aftersell/cart/custom-css) を参照してください。
* **`shadowRoot` の存在を確認**してから使用する。カートが起動するまでは `undefined` です。
* **ブロックはカートが読み込まれるまで何もレンダリングしない**ため、ゲートが適用される前にチェックアウトボタンが一瞬有効になることはありません。
* **例外をスローした React ブロックは何もレンダリングせず**、カートの残りはそのまま動き続けます。ここではそれがガードされていないチェックアウトボタンを意味します。公開前にプレビューでテストしてください。

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

* **[カスタムコードブロック](/ja/aftersell/cart/custom-code-blocks)**: React モードとその props。
* **[カスタム CSS](/ja/aftersell/cart/custom-css)**: 公開クラスの命名規則。
* **[イベント](/ja/aftersell/cart/sdk-events#checkout)**: `checkout` イベントでできること、できないこと。
