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

# Solid

> Integrate Commerce Engine Checkout into SolidJS apps with fine-grained reactive signals.

`useCheckout()` returns an object whose state properties are reactive Solid getters. Keep the object intact rather than destructuring reactive values.

## Installation

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
npm install @commercengine/checkout
```

Choose the authentication mode:

| Application architecture | Mode |
| - | - |
| Hosted Checkout is the only Commerce Engine integration | `managed` |
| App also uses `@commercengine/storefront` or direct session APIs | `provided` with two-way token sync |

## Checkout-only Solid app

```tsx src/App.tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { onCleanup, onMount } from "solid-js";
import {
  destroyCheckout,
  initCheckout,
  useCheckout,
} from "@commercengine/checkout/solid";

export default function App() {
  onMount(() => {
    initCheckout({
      storeId: import.meta.env.VITE_STORE_ID,
      apiKey: import.meta.env.VITE_API_KEY,
      environment:
        import.meta.env.VITE_CE_ENV === "production"
          ? "production"
          : "staging",
      onComplete: ({ orderNumber }) => {
        window.location.assign(`/thank-you?order=${orderNumber}`);
      },
    });
  });

  onCleanup(() => destroyCheckout());

  const checkout = useCheckout();

  return (
    <button
      type="button"
      onClick={() => checkout.openCart()}
      disabled={!checkout.isReady}
    >
      Cart ({checkout.cartCount})
    </button>
  );
}
```

## Solid app with Storefront SDK

Configure SDK-to-checkout token updates inside `session`:

```typescript src/lib/storefront.ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { getCheckout } from "@commercengine/checkout";
import {
  BrowserTokenStorage,
  Environment,
  createStorefront,
} from "@commercengine/storefront";

export const tokenStorage = new BrowserTokenStorage("brand_");

export const storefront = createStorefront({
  storeId: import.meta.env.VITE_STORE_ID,
  apiKey: import.meta.env.VITE_API_KEY,
  environment:
    import.meta.env.VITE_CE_ENV === "production"
      ? Environment.Production
      : Environment.Staging,
  session: {
    tokenStorage,
    onTokensUpdated: (accessToken, refreshToken) => {
      getCheckout().updateTokens(accessToken, refreshToken);
    },
  },
});

export const sdk = storefront.session();
```

Initialize provided mode and guard cleanup:

```tsx src/StorefrontBootstrap.tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { onCleanup, onMount } from "solid-js";
import {
  destroyCheckout,
  initCheckout,
} from "@commercengine/checkout/solid";
import { sdk, tokenStorage } from "./lib/storefront";

export function StorefrontBootstrap() {
  let active = true;

  onMount(async () => {
    try {
      const accessToken = await sdk.ensureAccessToken();
      const refreshToken = await tokenStorage.getRefreshToken();
      if (!active) return;

      initCheckout({
        storeId: import.meta.env.VITE_STORE_ID,
        apiKey: import.meta.env.VITE_API_KEY,
        environment:
          import.meta.env.VITE_CE_ENV === "production"
            ? "production"
            : "staging",
        authMode: "provided",
        accessToken: accessToken ?? undefined,
        refreshToken: refreshToken ?? undefined,
        onTokensUpdated: ({ accessToken, refreshToken }) => {
          void sdk.setTokens(accessToken, refreshToken);
        },
      });
    } catch (error) {
      console.error("Commerce Engine startup failed", error);
    }
  });

  onCleanup(() => {
    active = false;
    destroyCheckout();
  });

  return null;
}
```

Mount `<StorefrontBootstrap />` once near the application root.

## Use the primitive

```tsx src/CartButton.tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { useCheckout } from "@commercengine/checkout/solid";

export function CartButton() {
  const checkout = useCheckout();

  return (
    <button
      type="button"
      disabled={!checkout.isReady}
      onClick={() => checkout.openCart()}
    >
      Cart ({checkout.cartCount})
    </button>
  );
}
```

<Warning>
  Do not destructure reactive state such as `const { cartCount } = useCheckout()`. Destructuring reads the getter once and can break reactivity. Call methods and read properties through the returned object.
</Warning>

```tsx src/AddToCartButton.tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { useCheckout } from "@commercengine/checkout/solid";

export function AddToCartButton(props: {
  productId: string;
  variantId: string | null;
  hasVariants: boolean;
}) {
  const checkout = useCheckout();

  return (
    <button
      type="button"
      disabled={!checkout.isReady || (props.hasVariants && !props.variantId)}
      onClick={() => checkout.addToCart(props.productId, props.variantId, 1)}
    >
      Add to cart
    </button>
  );
}
```

## SolidStart

Initialize checkout only in the browser lifecycle. Keep server imports free of checkout browser code. When the application uses a Commerce Engine Storefront session, use the appropriate request-bound SSR integration plus provided-mode checkout in a root client component.

```tsx src/components/CheckoutBootstrap.tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { onCleanup, onMount } from "solid-js";

export function CheckoutBootstrap() {
  let active = true;
  let destroy: (() => void) | undefined;

  onMount(async () => {
    const checkout = await import("@commercengine/checkout/solid");
    if (!active) return;

    checkout.initCheckout({
      storeId: import.meta.env.VITE_STORE_ID,
      apiKey: import.meta.env.VITE_API_KEY,
      environment:
        import.meta.env.VITE_CE_ENV === "production"
          ? "production"
          : "staging",
    });

    destroy = checkout.destroyCheckout;
  });

  onCleanup(() => {
    active = false;
    destroy?.();
  });

  return null;
}
```

Mount `<CheckoutBootstrap />` inside the SolidStart root component. The lifecycle hooks must run under a Solid owner; do not call them at module scope.

## Fine-grained signals

For a component that only needs one state value:

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { createCartCountSignal } from "@commercengine/checkout/solid";

export function CartBadge() {
  const cartCount = createCartCountSignal();
  return <span aria-live="polite">{cartCount()}</span>;
}
```

Available signal creators include `createCartCountSignal` and `createIsReadySignal`.

## Primitive API

| Property | Type | Description |
| - | - | - |
| `isReady` | reactive getter | iframe ready state |
| `isOpen` | reactive getter | overlay visibility |
| `cartCount` | reactive getter | item count |
| `cartTotal` | reactive getter | reported total |
| `cartCurrency` | reactive getter | currency code |
| `isLoggedIn` | reactive getter | login state |
| `user` | reactive getter | current user |
| `openCart()` | function | open cart drawer |
| `openCheckout()` | function | open checkout directly |
| `close()` | function | close overlay |
| `addToCart(productId, variantId, quantity?)` | function | add item |
| `updateTokens(accessToken, refreshToken?)` | function | update provided-mode tokens |

## Production checklist

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
[ ] useCheckout return object is not destructured
[ ] checkout initialized in browser lifecycle once
[ ] cleanup registered
[ ] async initialization guarded against teardown
[ ] provided mode used when Storefront SDK is present
[ ] two-way token synchronization works
[ ] cart controls wait for isReady
[ ] variant ID is resolved correctly
```

<Card title="Production storefront references" icon="github" href="https://github.com/tark-ai/ce-starter-projects">
  Use the multi-framework starters to compare Solid's client lifecycle with production SSR and edge deployment patterns.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.