> ## 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 SDK の仕組み: グローバルなエントリーポイント、API の 4 つの構成要素、読み込みのタイミング、そして安全にコードを実行する方法。

**Cart SDK** は、ストアフロント上の Aftersell Cart のための JavaScript API です。カートの動作を変更したり、買い物客の行動に反応したり、コードからカートの内容を読み取ったり変更したりできます。

SDK コードは、[カスタムスクリプト](/ja/aftersell/cart/custom-scripts)を通じて、または独自の UI をレンダリングするブロックの場合は [Custom code ブロック](/ja/aftersell/cart/custom-code-blocks)の React モードを通じて実行します。

<Note>
  マーチャントが SDK に求めることの多くは、すでに設定として存在します。スクリプトを書く前に、[カートブロック](/ja/aftersell/cart/blocks-overview)、[マーケット/国/通貨による条件](/ja/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency)、または[カート設定](/ja/aftersell/cart/cart-settings)がすでにそれを実現していないか確認してください。それらはカートの再設計後も機能し続けますが、スクリプトはそうとは限りません。
</Note>

<div id="the-global-entry-point">
  ## グローバルなエントリーポイント
</div>

すべては 1 つのグローバルにぶら下がっています:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart
```

<Note>
  **このドキュメントのすべてのスニペットは `window.aftersell.cart` を完全に書き出しています**。そのため、どれか 1 つを貼り付けるだけで単独で動きます。一度エイリアスを作って（`const cart = window.aftersell.cart;`）以降 `cart` を使うのもまったく有効で、カートの読み込み前でも安全です。ただしスニペットを短縮する場合はその行を含めることを忘れないでください。`cart` 単体では `cart is not defined` が投げられます。
</Note>

4 つの構成要素が仕事をします:

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/ja/aftersell/cart/sdk-configure">
    カートの動作を設定します: ドロワーが開くタイミング、金額のフォーマット方法、Aftersell がカート追加をインターセプトするかどうか。
  </Card>

  <Card title="イベント" icon="tower-broadcast" href="/ja/aftersell/cart/sdk-events">
    起こったことに反応します: カートが読み込まれた、アイテムが追加された、ドロワーが開いた、チェックアウトがクリックされた。
  </Card>

  <Card title="アクション" icon="wand-magic-sparkles" href="/ja/aftersell/cart/sdk-actions">
    カートを読み取り、変更します: 開く、アイテムを追加する、数量を更新する、現在の状態を読み取る。
  </Card>

  <Card title="フック" icon="plug" href="/ja/aftersell/cart/sdk-hooks">
    カート自体の動作を変更します: ラインの非表示やラベル変更、並べ替え、追加データの付与、カート追加の制御。
  </Card>
</Columns>

<Note>
  あなたのスクリプトがカート追加で発火しなくなった場合は、まず[カート追加のインターセプト](/ja/aftersell/cart/add-to-cart-interception)から確認してください。Aftersell がなぜ追加を引き受けるのか、そしてフォームをオプトアウトさせるあらゆる方法が説明されています。
</Note>

さらに 3 つの小さなメンバーがあります:

| メンバー         | 用途                                      |
| ------------ | --------------------------------------- |
| `ready()`    | カートの初回読み込みが完了すると解決される Promise。          |
| `context`    | サーバーでレンダリングされた購入者コンテキスト。同期的に読み取れます。     |
| `shadowRoot` | カートの shadow root。ドロワー内の要素をクエリするために使います。 |

<div id="events-actions-or-hooks">
  ## イベント、アクション、それともフック？
</div>

この 3 つは混同しやすく、間違ったものを選ぶことが、スクリプトが作者の期待どおりに動かない最も一般的な原因です:

| やりたいこと                 | 使うもの      | 例                         |
| ---------------------- | --------- | ------------------------- |
| *何かが起こったとき*にコードを実行する   | **イベント**  | アイテム追加時にアナリティクスイベントを送信する。 |
| カートの*中身を変更*する          | **アクション** | 合計が \$50 を超えたら無料ギフトを追加する。 |
| *カートの動作やレンダリング方法*を変更する | **フック**   | 無料ギフトのラインをドロワーから非表示にする。   |

最も重要な区別: **アクションは買い物客の実際のカート**（と合計金額）を変更し、**フックはレンダリングされるものだけ**を変更します。フックでラインを非表示にしてもカートと合計には残りますが、アクションで削除すれば実際に取り除かれます。

<div id="how-and-when-it-loads">
  ## 読み込みの方法とタイミング
</div>

カートは 2 段階で読み込まれ、SDK は順序を気にしなくて済むように作られています:

1. 小さな**スタブ**が `window.aftersell.cart` を即座に作成するため、常に存在します。
2. その直後に完全な SDK が読み込まれて引き継ぎ、スタブをその場でアップグレードするため、先に取得した参照はそのまま使い続けられます。

これにより、呼び出しは 2 つのカテゴリに分かれます:

<Columns cols={2}>
  <Card title="セットアップの呼び出し: すぐに安全" icon="circle-check">
    `configure(...)`、`events.on(...)`、すべての `hooks.register*` 呼び出し。起動前はバッファリングされ、SDK が読み込まれると順番に再生されます。スクリプトの冒頭に置いてください。
  </Card>

  <Card title="アクション: ready() を待つ" icon="clock">
    `actions.*` の下にあるすべて。`ready()` の中またはイベントハンドラの中で実行してください。早く呼びすぎるとコンソールに警告を出して何もしませんが、安全です: 非同期のものは解決されるため、`.then()` チェーンは壊れません。
  </Card>
</Columns>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Set-up: fine at the top level, before the cart has loaded.
window.aftersell.cart.configure({ open_on_add_to_cart: 'always' });

window.aftersell.cart.events.on('item_added', (payload) => {
  console.log('Added', payload.item.title);
});

// Actions: wait until the cart is ready.
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log(state.itemCount, 'items');
});
```

<div id="ready">
  ### ready()
</div>

`ready()` は、最初のカート読み込みが**確定**すると解決される Promise を返します。成功時だけでなく失敗時にも解決されるため、不安定な接続の買い物客でもスクリプトが宙吊りになることはありません。カートが届いたと想定せず、`getCart()` が `null` でないか確認してください。

カートの読み込み後に `ready()` を呼ぶと即座に解決されるため、コードのどこでも「カートは今存在する」という汎用のゲートとして安全に使えます。

<Tip>
  イベントハンドラの中では `ready()` は不要です。`cart_loaded`、`cart_updated`、`item_added` が発火する時点で、カートは読み込まれておりアクションを安全に呼び出せます。
</Tip>

<div id="context">
  ## context
</div>

`window.aftersell.cart.context` は、サーバーがレンダリングした購入者データを保持し、`ready()` なしで同期的に読み取れます。カートの読み込み前に行う必要があるマーケットや国による分岐に使ってください。

| フィールド                     | 説明                                           | 起動前に利用可能                 |
| ------------------------- | -------------------------------------------- | ------------------------ |
| `shopify_market`          | 購入者の Shopify マーケット。                          | はい                       |
| `customer_country`        | 2 文字の国コード。                                   | はい                       |
| `customer_currency`       | 有効な通貨コード。                                    | はい                       |
| `money_format`            | ストアの Shopify 金額フォーマット。                       | はい                       |
| `backend_url`             | 直接のバックエンドホスト。アプリプロキシが未設定の場合のフォールバックとして使われます。 | はい                       |
| `storefront_access_token` | Storefront API 呼び出し用のトークン。                   | **いいえ** — カートの起動時に追加されます |

<Warning>
  `storefront_access_token` は、サーバーが `cart.context` にレンダリングしない唯一の `context` フィールドです。カートの起動時に `context` に追加されるため、スクリプトの冒頭で読むと `undefined` になります。まず `window.aftersell.cart.ready()` を await してください。
</Warning>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
if (window.aftersell.cart.context.customer_country === 'CA') {
  // Canada-only behavior, decided before the cart loads.
}
```

<Note>
  マーケット、国、通貨ごとに異なるブロック設定を表示するには、代わりに[カートエディタの条件](/ja/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency)を使ってください。スクリプトは不要です。完全な Conditions UI は現在 [Rewards](/ja/aftersell/cart/rewards-block#per-market-rewards) で提供されています。
</Note>

<div id="shadowroot">
  ## shadowRoot
</div>

カートは shadow root 内でレンダリングされるため、`document.querySelector` では**ドロワー内の何も見えません**。カート内の要素にアクセスするには、shadow root をクエリしてください:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const root = window.aftersell.cart.shadowRoot;
const button = root?.querySelector('.cart-external-checkout-button');
```

[Custom CSS](/ja/aftersell/cart/custom-css) が使うのと同じ**公開の `cart-external-*` クラス**を対象にしてください。それらがサポートされたハンドルです。対になる `cart-internal-*` はカート自身の内部機構なので、external の方をクエリしてください。

<Warning>
  shadow root に手を伸ばすのは、どのブロック、設定、フックでも実現できない場合だけにしてください。フックはカートの再設計を生き延びますが、DOM クエリの保守はあなたのコードの問題です。
</Warning>

shadow root はカートが起動してから存在するため、スクリプトの冒頭ではなく、`ready()` の中またはイベントハンドラの中で読み取ってください。

<div id="debugging">
  ## デバッグ
</div>

壊れたスクリプトがカート追加やドロワーを止めることは決してあってはならないため、SDK は失敗をバブルさせずに封じ込めます。失敗がどこに現れるかは、何が壊れたかによります:

| 失敗したもの                                                  | 現れる場所                              |
| ------------------------------------------------------- | ---------------------------------- |
| スクリプトがトップレベルで throw した                                  | `console.error`。行と実行されなかった内容が示されます |
| [イベント](/ja/aftersell/cart/sdk-events)ハンドラが throw した     | `console.error`。他のハンドラは引き続き実行されます  |
| [フック](/ja/aftersell/cart/sdk-hooks)が throw した           | 無音。下記のデバッグチャンネルに送られます              |
| カートの読み込み前に[アクション](/ja/aftersell/cart/sdk-actions)が実行された | `console.warn`。呼び出しは何もしません         |

<div id="when-your-script-throws">
  ### スクリプトが throw したとき
</div>

カスタムスクリプトは**最初のエラーで停止**するため、その行より下のすべての `configure`、`events.on`、`hooks.register*` は実行されません。カートはそれを明示的に伝えます:

```
[aftersell-cart] Initialization script error on line 12 — 4 more line(s) did not run;
any configure/events/hooks below are unregistered.
```

確かに登録したはずのハンドラが発火しないときに探すべきメッセージがこれです。おそらくその行に到達していません。行番号は実行が停止したトップレベルのステートメントであり、throw した内側の関数ではありません。ブラウザのスタックが使えない場合は、推測されるのではなく省略されます。

スクリプトは独自のファイル名でも実行されるため、DevTools では `aftersell-cart-init.js` と `aftersell-cart-cart-update.js` として表示されます。Sources パネルから開き、他のファイルと同じようにブレークポイントを設定できます。

<div id="the-debug-channel">
  ### デバッグチャンネル
</div>

フックの失敗は、買い物客の目に触れないよう意図的にコンソールに出しません。代わりにここに送られます:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// After reproducing the problem, inspect what was swallowed:
window.aftersellCartDebugEvents.filter((entry) => entry.level === 'ERROR');

// Or watch them live:
window.addEventListener('aftersell-cart-debug', (event) => console.log(event.detail));
```

<div id="where-to-go-next">
  ## 次のステップ
</div>

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/ja/aftersell/cart/sdk-configure">
    すべてのオプションを、それぞれ例付きで。
  </Card>

  <Card title="イベント" icon="tower-broadcast" href="/ja/aftersell/cart/sdk-events">
    すべてのイベント、発火タイミング、そしてハンドラでやってはいけないこと。
  </Card>

  <Card title="アクション" icon="wand-magic-sparkles" href="/ja/aftersell/cart/sdk-actions">
    すべてのアクションを、それぞれスニペット付きで。
  </Card>

  <Card title="フック" icon="plug" href="/ja/aftersell/cart/sdk-hooks">
    すべてのフックと、登録がどのように合成されるか。
  </Card>

  <Card title="カートオブジェクト" icon="table-list" href="/ja/aftersell/cart/sdk-cart-object">
    カートとそのラインの構造。
  </Card>

  <Card title="ユースケース" icon="book-open" href="/ja/aftersell/cart/sdk-use-cases">
    よくある要望に対する、完全ですぐ実行できるソリューション。
  </Card>
</Columns>
