Manifest Debugger

Using react-docgen-typescript. Generation took 0.7s.

Components

AddToCartButton

components-cart-addtocartbutton · ./src/stories/cart/AddToCartButton.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import {
    AddToCartButton,
    AvailabilityContainer,
    AvailabilityTemplate,
    CommerceLayer,
    Errors,
    LineItem,
    LineItemName,
    LineItemQuantity,
    LineItemRemoveLink,
    LineItemsContainer,
    LineItemsEmpty,
    Order,
    OrderStorage,
    Skus,
    SkusContainer,
} from "@commercelayer/react-components";
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
Add SKU to cart story ok
const AddSku = () => <Wrapper>
    <AddToCartButton
        skuCode="SWEATWCX000000FFFFFFXSXX"
        label="Add SKU to cart"
        quantity="2"
        className="px-3 py-2 bg-black text-white rounded disabled:opacity-50" />
</Wrapper>;
Add bundle to cart story ok
const AddBundle = () => <Wrapper>
    <AddToCartButton
        bundleCode="BUNDLE001"
        label="Add bundle to cart"
        quantity="2"
        className="px-3 py-2 bg-black text-white rounded disabled:opacity-50" />
</Wrapper>;
Disabled when out of stock story ok
Combine `<AddToCartButton>` with `<AvailabilityTemplate>` to automatically disable the button when the SKU is out of stock.
const DisabledWhenOutOfStock = () => (
  <Wrapper>
    <SkusContainer skus={["POLOMXXX000000FFFFFFLXXX", "TSHIRTWV000000FFFFFFSXXX"]}>
      <Skus>
        <AvailabilityContainer>
          <AvailabilityTemplate>
            {({ quantity }) => (
              <div className="mb-4 grid max-w-md">
                Quantity available: {quantity}
                <AddToCartButton
                  className="px-3 py-2 bg-black text-white rounded disabled:opacity-50"
                  disabled={quantity <= 0}
                />
              </div>
            )}
          </AvailabilityTemplate>
        </AvailabilityContainer>
      </Skus>
    </SkusContainer>
  </Wrapper>
);
Custom attributes / external price story ok
Pass a `lineItem` prop to customise the created line item attributes — useful for custom names or enabling external prices. <span title="Core API" type="info"> See the [line_items API reference](https://docs.commercelayer.io/core/v/api-reference/line_items/object). </span>
const UseCustomAttributesOrExternalPrice = () => (
  <Wrapper>
    <AddToCartButton
      label="Add with custom name"
      skuCode="SWEATWCX000000FFFFFFXSXX"
      className="px-3 py-2 bg-black text-white rounded disabled:opacity-50"
      lineItem={{
        name: "My custom item name",
        externalPrice: false,
      }}
    />
  </Wrapper>
);
Children props (render prop) story ok
Use the `children` render prop to fully control the button UI. The `disabled` prop reflects the loading state — it is `true` while the cart operation is in progress, preventing double-clicks automatically.
const ChildrenProps = () => (
  <Wrapper>
    <AddToCartButton skuCode="SWEATWCX000000FFFFFFXSXX" quantity="1">
      {({ handleClick, disabled }) => (
        <button
          type="button"
          className="border-dotted border-2 border-blue-500 text-blue-500 p-4 w-auto inline"
          onClick={() => {
            void handleClick().then(({ orderId, success }) => {
              if (success) {
                alert(`Item added to cart — orderId: ${orderId}`)
              }
            })
          }}
        >
          {disabled ? "Adding…" : "Add to cart"}
        </button>
      )}
    </AddToCartButton>
  </Wrapper>
);

Availability

components-availability-availability · ./src/stories/availability/availability.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { Availability, AvailabilityTemplate, CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
Availability — standalone (no container) story ok
const StandaloneAvailability = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "In stock", outOfStock: "Out of stock" }} />
    </Availability>
  </CommerceLayer>
);
Availability — getQuantity callback story ok
const WithGetQuantityCallback = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability
      skuCode="POLOMXXX000000FFFFFFLXXX"
      getQuantity={(quantity) => {
        console.log("quantity updated:", quantity)
      }}
    >
      <AvailabilityTemplate />
    </Availability>
  </CommerceLayer>
);
Availability — inside Sku (inherits skuCode) story ok
const InsideSku = () => (
  <CommerceLayer accessToken="my-access-token">
    <Sku skuCode="POLOMXXX000000FFFFFFLXXX">
      <SkuField attribute="name" tagElement="h3" style={{ marginBottom: 4 }} />
      <Availability>
        <AvailabilityTemplate />
      </Availability>
    </Sku>
  </CommerceLayer>
);

AvailabilityContainer

components-availability-availabilitycontainer · ./src/stories/availability/AvailabilityContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { AvailabilityContainer, AvailabilityTemplate, CommerceLayer } from "@commercelayer/react-components";
AvailabilityContainer — deprecated (legacy) story ok
const DeprecatedContainer = () => (
  <CommerceLayer accessToken="my-access-token">
    <AvailabilityContainer skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate />
    </AvailabilityContainer>
  </CommerceLayer>
);

AvailabilityTemplate

components-availability-availabilitytemplate · ./src/stories/availability/AvailabilityTemplate.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { Availability, AvailabilityTemplate, CommerceLayer } from "@commercelayer/react-components";
AvailabilityTemplate — custom labels story ok
const CustomLabels = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate
        labels={{
          available: "✅ In stock",
          outOfStock: "❌ Sold out",
          negativeStock: "⚠️ Not available",
        }}
      />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — lead time in days story ok
const WithDeliveryLeadTimeDays = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "Available" }} timeFormat="days" />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — lead time in hours story ok
const WithDeliveryLeadTimeHours = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "Available" }} timeFormat="hours" />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — with shipping method name story ok
const WithShippingMethodName = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate timeFormat="days" showShippingMethodName />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — with shipping method price story ok
const WithShippingMethodPrice = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate timeFormat="days" showShippingMethodName showShippingMethodPrice />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — children render prop story ok
const WithChildrenRenderProp = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate>
        {({ quantity, text, min, max }) => (
          <div style={{ fontFamily: "monospace", fontSize: 14 }}>
            <strong>{text}</strong>
            {quantity > 0 && min != null && (
              <p style={{ marginTop: 4, color: "#666" }}>
                Ships in {min.days}–{max?.days ?? min.days} day(s)
              </p>
            )}
          </div>
        )}
      </AvailabilityTemplate>
    </Availability>
  </CommerceLayer>
);

CartLink

components-cart-cartlink · ./src/stories/cart/CartLink.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import {
    CartLink,
    CommerceLayer,
    HostedCart,
    Order,
    OrderStorage as OrderStorageHelper,
} from "@commercelayer/react-components";
Default — link to hosted cart story ok
The default `<CartLink>` renders an `<a>` tag that navigates to the Commerce Layer hosted cart application when clicked.
const Default = () => <Wrapper>
    <CartLink label="View cart" className="text-blue-600 underline hover:text-blue-800" />
</Wrapper>;
Mini cart trigger story ok
Set `type="mini"` so clicking the link publishes the `"open-cart"` event instead of navigating. A `<HostedCart type="mini">` on the same page listens for this event and opens the slide-in panel.
const MiniCartTrigger = () => {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <Wrapper>
      <CartLink
        type="mini"
        label="Open mini cart"
        className="px-4 py-2 bg-black text-white rounded text-sm"
      />
      <HostedCart type="mini" open={isOpen} handleOpen={() => setIsOpen((o) => !o)} />
    </Wrapper>
  )
};
Children props (render prop) story ok
Use the `children` render prop to fully control the trigger element. The `href` and `handleClick` props are provided by `CartLink` and wire up navigation automatically.
const ChildrenProps = () => (
  <Wrapper>
    <CartLink target="_blank">
      {({ href, handleClick, orderId }) => (
        <a
          href={href}
          onClick={handleClick}
          className="inline-flex items-center gap-2 rounded bg-black px-4 py-2 text-sm text-white hover:bg-gray-800"
        >
          🛒 Cart{orderId != null ? ` — order ${orderId}` : ""}
        </a>
      )}
    </CartLink>
  </Wrapper>
);

CheckoutLink

components-orders-checkoutlink · ./src/stories/orders/CheckoutLink.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CheckoutLink, CommerceLayer, Order, OrderStorage as OrderStorageHelper } from "@commercelayer/react-components";
Default — hosted checkout story ok
const Default = () => <Wrapper>
    <CheckoutLink
        label="Go to checkout"
        className="text-blue-600 underline hover:text-blue-800"
        target="_blank" />
</Wrapper>;
Using order checkout_url story ok
const WithOrderCheckoutUrl = () => <Wrapper>
    <CheckoutLink
        label="Checkout via order URL"
        hostedCheckout={false}
        className="text-blue-600 underline hover:text-blue-800" />
</Wrapper>;
Children props (render prop) story ok
Use the `children` render prop to fully control the rendered element. The `href` and `handleClick` props are provided by the component and wire up the organization-config-aware navigation automatically.
const ChildrenProps = () => (
  <Wrapper>
    <CheckoutLink>
      {({ href, handleClick }) => (
        <a
          href={href}
          onClick={handleClick}
          className="inline-flex items-center gap-2 rounded bg-black px-4 py-2 text-sm text-white hover:bg-gray-800"
        >
          Proceed to checkout →
        </a>
      )}
    </CheckoutLink>
  </Wrapper>
);

HostedCart

components-cart-hostedcart · ./src/stories/cart/HostedCart.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, HostedCart, Order, OrderStorage as OrderStorageHelper } from "@commercelayer/react-components";
Default — inline cart story ok
The default inline cart renders an `<iframe>` that fills the container width. The iframe height is managed automatically by `iframe-resizer`.
const Default = () => <Wrapper>
    <HostedCart />
</Wrapper>;
Custom domain story ok
Pass `customDomain` to load a self-hosted or forked cart application instead of the default Commerce Layer hosted micro-frontend.
const CustomDomain = () => <Wrapper>
    <HostedCart customDomain="cart.my-store.com" />
</Wrapper>;

HostedCart

components-cart-minicart · ./src/stories/cart/MiniCart.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import {
    AddToCartButton,
    CartLink,
    CommerceLayer,
    HostedCart,
    Order,
    OrderStorage as OrderStorageHelper,
} from "@commercelayer/react-components";
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
Mini cart story ok
Controlled mini cart: `open` and `handleOpen` are wired to local state so the panel can be opened with the button and closed by clicking the overlay or the close icon inside the cart iframe.
const Default = () => {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <Wrapper>
      <CartLink
        type="mini"
        label="Open mini cart"
        className="px-4 py-2 bg-black text-white rounded text-sm"
      />
      <HostedCart type="mini" open={isOpen} handleOpen={() => setIsOpen((o) => !o)} />
    </Wrapper>
  )
};
Auto-open on add to cart story ok
When `openAdd` is `true` the panel opens automatically after `<AddToCartButton>` successfully adds an item. The `"open-cart"` event is published internally by `AddToCartButton` on success.
const OpenOnAdd = () => <Wrapper>
    <AddToCartButton
        skuCode="SWEATWCX000000FFFFFFXSXX"
        label="Add to cart"
        quantity="1"
        className="px-4 py-2 bg-black text-white rounded text-sm disabled:opacity-50" />
    <HostedCart type="mini" openAdd />
</Wrapper>;

Order

components-orders-order · ./src/stories/orders/Order.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import {
    CommerceLayer,
    DiscountAmount,
    Order,
    OrderNumber,
    ShippingAmount,
    SubTotalAmount,
    TaxesAmount,
    TotalAmount,
} from "@commercelayer/react-components";
Order — display order details story ok
const OrderStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Order orderId="KaeheROdbp">
      <div style={{ display: "grid", gap: 8, minWidth: 240 }}>
        <div>
          Order #<OrderNumber />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Subtotal</span>
          <SubTotalAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Discount</span>
          <DiscountAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Shipping</span>
          <ShippingAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Taxes</span>
          <TaxesAmount />
        </div>
        <hr />
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            fontWeight: "bold",
          }}
        >
          <span>Total</span>
          <TotalAmount />
        </div>
      </div>
    </Order>
  </CommerceLayer>
);
Order — with fetchOrder callback story ok
const OrderWithCallbackStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Order
      orderId="KaeheROdbp"
      fetchOrder={(order) => {
        console.log("fetchOrder: ", order)
      }}
    >
      <div>
        Order #<OrderNumber />
      </div>
      <div>
        Total: <TotalAmount />
      </div>
    </Order>
  </CommerceLayer>
);

OrderContainer

components-orders-ordercontainer · ./src/stories/orders/OrderContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, OrderContainer, OrderNumber, TotalAmount } from "@commercelayer/react-components";
OrderContainer — display order details story ok
const OrderContainerStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <OrderContainer orderId="KaeheROdbp">
      <div>
        Order #<OrderNumber />
      </div>
      <div>
        Total: <TotalAmount />
      </div>
    </OrderContainer>
  </CommerceLayer>
);

Price

components-prices-price · ./src/stories/prices/prices.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Price } from "@commercelayer/react-components";
Price — children render prop story ok
const RenderPropStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Price skuCode="POST6191FFFFFF000000XXXX">
      {({ prices, loading }) => {
        if (loading) return <span style={{ color: "#999" }}>Loading…</span>
        if (prices.length === 0) return <span style={{ color: "red" }}>No price available</span>
        const [p] = prices
        return (
          <div>
            <strong style={{ fontSize: "1.25rem" }}>{p.formatted_amount}</strong>
            {p.formatted_compare_at_amount != null && (
              <s style={{ marginLeft: 8, color: "#999" }}>{p.formatted_compare_at_amount}</s>
            )}
          </div>
        )
      }}
    </Price>
  </CommerceLayer>
);
Price — standalone story ok
const StandalonePrice = () => (
  <CommerceLayer accessToken="my-access-token">
    <div style={{ display: "grid", gap: 12 }}>
      <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
        <span style={{ width: 240, fontSize: "0.85rem", color: "#666" }}>
          POST6191FFFFFF000000XXXX
        </span>
        <Price
          skuCode="POST6191FFFFFF000000XXXX"
          style={{ fontWeight: "bold" }}
          loader={<span style={{ color: "#bbb", fontSize: "0.8rem" }}>…</span>}
        />
      </div>
      <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
        <span style={{ width: 240, fontSize: "0.85rem", color: "#666" }}>
          POLOMXXX000000FFFFFFLXXX
        </span>
        <Price
          skuCode="POLOMXXX000000FFFFFFLXXX"
          style={{ fontWeight: "bold" }}
          loader={<span style={{ color: "#bbb", fontSize: "0.8rem" }}>…</span>}
        />
      </div>
    </div>
  </CommerceLayer>
);

PricesContainer

components-prices-pricescontainer · ./src/stories/prices/PricesContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Price, PricesContainer } from "@commercelayer/react-components";
PricesContainer — single SKU story ok
const SingleSkuStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer skuCode="POST6191FFFFFF000000XXXX">
      <Price
        style={{ fontWeight: "bold", fontSize: "1.25rem" }}
        compareClassName="line-through ml-2"
      />
    </PricesContainer>
  </CommerceLayer>
);
PricesContainer — batched (single API request) story ok
const BatchedPricesStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer>
      <div style={{ display: "grid", gap: 12 }}>
        <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
          <span style={{ width: 220, fontSize: "0.85rem", color: "#666" }}>
            POST6191FFFFFF000000XXXX
          </span>
          <Price skuCode="POST6191FFFFFF000000XXXX" style={{ fontWeight: "bold" }} />
        </div>
        <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
          <span style={{ width: 220, fontSize: "0.85rem", color: "#666" }}>
            POLOMXXX000000FFFFFFLXXX
          </span>
          <Price skuCode="POLOMXXX000000FFFFFFLXXX" style={{ fontWeight: "bold" }} />
        </div>
      </div>
    </PricesContainer>
  </CommerceLayer>
);
PricesContainer — with filters story ok
const WithFiltersStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer skuCode="POST6191FFFFFF000000XXXX" filters={{ currency_code_eq: "EUR" }}>
      <Price style={{ fontWeight: "bold" }} />
    </PricesContainer>
  </CommerceLayer>
);

Sku

components-skus-sku · ./src/stories/skus/Sku.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
Sku — standalone (no container) story ok
const StandaloneSkuStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Sku skuCode="TSHIRTWS000000FFFFFFLXXX">
      <div style={{ marginBottom: 12 }}>
        <SkuField attribute="name" tagElement="h3" />
        <SkuField attribute="code" tagElement="p" />
      </div>
    </Sku>
    <Sku skuCode="TSHIRTWKFFFFFF000000MXXX">
      <div style={{ marginBottom: 12 }}>
        <SkuField attribute="name" tagElement="h3" />
        <SkuField attribute="code" tagElement="p" />
      </div>
    </Sku>
  </CommerceLayer>
);

SkuField

components-skus-skufield · ./src/stories/skus/SkusField.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
SkuField — text attribute story ok
const Default = () => <Wrapper>
    <SkuField attribute="name" tagElement="div" />
</Wrapper>;
SkuField — image_url as <img> story ok
const SkuImageAsImgTag = () => <Wrapper>
    <SkuField attribute="image_url" tagElement="img" width={100} />
</Wrapper>;
SkuField — children render prop story ok
Access the raw attribute value through the children render prop. Useful for custom rendering — e.g. iterating over `metadata` JSON.
const ChildrenProps = () => (
  <CommerceLayer accessToken="my-access-token" endpoint="https://demo-store.commercelayer.io">
    <Sku skuCode="5PANECAP9D9CA1FFFFFFXXXX">
      <SkuField attribute="metadata" tagElement="div">
        {(childrenProps: any) => (
          <pre style={{ fontSize: "0.75rem" }}>{JSON.stringify(childrenProps, null, 2)}</pre>
        )}
      </SkuField>
    </Sku>
  </CommerceLayer>
);

SkuList

components-skus-skulist · ./src/stories/skus/SkuList.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, Skus } from "@commercelayer/react-components";
SkuList — standalone (no container) story ok
const StandaloneSkuList = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuList id="yZjQIDxrly" params={{ fields: { skus: ["code", "name"] } }}>
      <Skus>
        <div style={{ marginBottom: 12 }}>
          <SkuField attribute="name" tagElement="h3" />
          <SkuField attribute="code" tagElement="p" />
        </div>
      </Skus>
    </SkuList>
  </CommerceLayer>
);

SkuListsContainer

components-skus-skulistscontainer · ./src/stories/skus/SkuListsContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, SkuListsContainer, Skus } from "@commercelayer/react-components";
SkuListsContainer — list items story ok
const SkuListsContainerStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuListsContainer params={{ fields: { skus: ["code", "name"] } }}>
      <SkuList id="yZjQIDxrly">
        <Skus>
          <div style={{ marginBottom: 12 }}>
            <SkuField attribute="name" tagElement="h3" />
            <SkuField attribute="code" tagElement="p" />
          </div>
        </Skus>
      </SkuList>
    </SkuListsContainer>
  </CommerceLayer>
);

Skus

components-skus-skus · ./src/stories/skus/skus.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, Skus } from "@commercelayer/react-components";
Skus — inside SkuList story ok
const Default = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuList id="yZjQIDxrly" params={{ fields: { skus: ["code", "name"] } }}>
      <Skus>
        <div style={{ marginBottom: 12 }}>
          <SkuField attribute="name" tagElement="h3" />
          <SkuField attribute="code" tagElement="p" />
        </div>
      </Skus>
    </SkuList>
  </CommerceLayer>
);

SkusContainer

components-skus-skuscontainer · ./src/stories/skus/SkusContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, Skus, SkusContainer } from "@commercelayer/react-components";
SkusContainer — name and code story ok
const Default = () => <CommerceLayer
    accessToken="my-access-token"
    endpoint="https://demo-store.commercelayer.io">
    <SkusContainer skus={["POLOMXXX000000FFFFFFLXXX", "CROPTOPWFFFFFF000000XSXX"]}>
        <Skus>
            <div style={{ marginBottom: 12 }}>
                <SkuField attribute="name" tagElement="h3" />
                <SkuField attribute="code" tagElement="p" />
            </div>
        </Skus>
    </SkusContainer>
</CommerceLayer>;
SkusContainer — with query params story ok
const WithQueryParams = () => <CommerceLayer
    accessToken="my-access-token"
    endpoint="https://demo-store.commercelayer.io">
    <SkusContainer
        skus={["POLOMXXX000000FFFFFFLXXX", "CROPTOPWFFFFFF000000XSXX"]}
        queryParams={{
          pageSize: 25,
          pageNumber: 1,
          fields: ["name", "description", "image_url", "reference"],
          sort: { name: "asc" },
        }}>
        <Skus>
            <div style={{ marginBottom: 12 }}>
                <SkuField attribute="name" tagElement="h3" />
                <SkuField attribute="code" tagElement="p" />
            </div>
        </Skus>
    </SkusContainer>
</CommerceLayer>;

AddToCartButton

components-cart-addtocartbutton · ./src/stories/cart/AddToCartButton.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import {
    AddToCartButton,
    AvailabilityContainer,
    AvailabilityTemplate,
    CommerceLayer,
    Errors,
    LineItem,
    LineItemName,
    LineItemQuantity,
    LineItemRemoveLink,
    LineItemsContainer,
    LineItemsEmpty,
    Order,
    OrderStorage,
    Skus,
    SkusContainer,
} from "@commercelayer/react-components";
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
Add SKU to cart story ok
const AddSku = () => <Wrapper>
    <AddToCartButton
        skuCode="SWEATWCX000000FFFFFFXSXX"
        label="Add SKU to cart"
        quantity="2"
        className="px-3 py-2 bg-black text-white rounded disabled:opacity-50" />
</Wrapper>;
Add bundle to cart story ok
const AddBundle = () => <Wrapper>
    <AddToCartButton
        bundleCode="BUNDLE001"
        label="Add bundle to cart"
        quantity="2"
        className="px-3 py-2 bg-black text-white rounded disabled:opacity-50" />
</Wrapper>;
Disabled when out of stock story ok
Combine `<AddToCartButton>` with `<AvailabilityTemplate>` to automatically disable the button when the SKU is out of stock.
const DisabledWhenOutOfStock = () => (
  <Wrapper>
    <SkusContainer skus={["POLOMXXX000000FFFFFFLXXX", "TSHIRTWV000000FFFFFFSXXX"]}>
      <Skus>
        <AvailabilityContainer>
          <AvailabilityTemplate>
            {({ quantity }) => (
              <div className="mb-4 grid max-w-md">
                Quantity available: {quantity}
                <AddToCartButton
                  className="px-3 py-2 bg-black text-white rounded disabled:opacity-50"
                  disabled={quantity <= 0}
                />
              </div>
            )}
          </AvailabilityTemplate>
        </AvailabilityContainer>
      </Skus>
    </SkusContainer>
  </Wrapper>
);
Custom attributes / external price story ok
Pass a `lineItem` prop to customise the created line item attributes — useful for custom names or enabling external prices. <span title="Core API" type="info"> See the [line_items API reference](https://docs.commercelayer.io/core/v/api-reference/line_items/object). </span>
const UseCustomAttributesOrExternalPrice = () => (
  <Wrapper>
    <AddToCartButton
      label="Add with custom name"
      skuCode="SWEATWCX000000FFFFFFXSXX"
      className="px-3 py-2 bg-black text-white rounded disabled:opacity-50"
      lineItem={{
        name: "My custom item name",
        externalPrice: false,
      }}
    />
  </Wrapper>
);
Children props (render prop) story ok
Use the `children` render prop to fully control the button UI. The `disabled` prop reflects the loading state — it is `true` while the cart operation is in progress, preventing double-clicks automatically.
const ChildrenProps = () => (
  <Wrapper>
    <AddToCartButton skuCode="SWEATWCX000000FFFFFFXSXX" quantity="1">
      {({ handleClick, disabled }) => (
        <button
          type="button"
          className="border-dotted border-2 border-blue-500 text-blue-500 p-4 w-auto inline"
          onClick={() => {
            void handleClick().then(({ orderId, success }) => {
              if (success) {
                alert(`Item added to cart — orderId: ${orderId}`)
              }
            })
          }}
        >
          {disabled ? "Adding…" : "Add to cart"}
        </button>
      )}
    </AddToCartButton>
  </Wrapper>
);

Availability

components-availability-availability · ./src/stories/availability/availability.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { Availability, AvailabilityTemplate, CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
Availability — standalone (no container) story ok
const StandaloneAvailability = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "In stock", outOfStock: "Out of stock" }} />
    </Availability>
  </CommerceLayer>
);
Availability — getQuantity callback story ok
const WithGetQuantityCallback = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability
      skuCode="POLOMXXX000000FFFFFFLXXX"
      getQuantity={(quantity) => {
        console.log("quantity updated:", quantity)
      }}
    >
      <AvailabilityTemplate />
    </Availability>
  </CommerceLayer>
);
Availability — inside Sku (inherits skuCode) story ok
const InsideSku = () => (
  <CommerceLayer accessToken="my-access-token">
    <Sku skuCode="POLOMXXX000000FFFFFFLXXX">
      <SkuField attribute="name" tagElement="h3" style={{ marginBottom: 4 }} />
      <Availability>
        <AvailabilityTemplate />
      </Availability>
    </Sku>
  </CommerceLayer>
);

AvailabilityContainer

components-availability-availabilitycontainer · ./src/stories/availability/AvailabilityContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { AvailabilityContainer, AvailabilityTemplate, CommerceLayer } from "@commercelayer/react-components";
AvailabilityContainer — deprecated (legacy) story ok
const DeprecatedContainer = () => (
  <CommerceLayer accessToken="my-access-token">
    <AvailabilityContainer skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate />
    </AvailabilityContainer>
  </CommerceLayer>
);

AvailabilityTemplate

components-availability-availabilitytemplate · ./src/stories/availability/AvailabilityTemplate.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { Availability, AvailabilityTemplate, CommerceLayer } from "@commercelayer/react-components";
AvailabilityTemplate — custom labels story ok
const CustomLabels = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate
        labels={{
          available: "✅ In stock",
          outOfStock: "❌ Sold out",
          negativeStock: "⚠️ Not available",
        }}
      />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — lead time in days story ok
const WithDeliveryLeadTimeDays = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "Available" }} timeFormat="days" />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — lead time in hours story ok
const WithDeliveryLeadTimeHours = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate labels={{ available: "Available" }} timeFormat="hours" />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — with shipping method name story ok
const WithShippingMethodName = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate timeFormat="days" showShippingMethodName />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — with shipping method price story ok
const WithShippingMethodPrice = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate timeFormat="days" showShippingMethodName showShippingMethodPrice />
    </Availability>
  </CommerceLayer>
);
AvailabilityTemplate — children render prop story ok
const WithChildrenRenderProp = () => (
  <CommerceLayer accessToken="my-access-token">
    <Availability skuCode="POLOMXXX000000FFFFFFLXXX">
      <AvailabilityTemplate>
        {({ quantity, text, min, max }) => (
          <div style={{ fontFamily: "monospace", fontSize: 14 }}>
            <strong>{text}</strong>
            {quantity > 0 && min != null && (
              <p style={{ marginTop: 4, color: "#666" }}>
                Ships in {min.days}–{max?.days ?? min.days} day(s)
              </p>
            )}
          </div>
        )}
      </AvailabilityTemplate>
    </Availability>
  </CommerceLayer>
);

CartLink

components-cart-cartlink · ./src/stories/cart/CartLink.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import {
    CartLink,
    CommerceLayer,
    HostedCart,
    Order,
    OrderStorage as OrderStorageHelper,
} from "@commercelayer/react-components";
Default — link to hosted cart story ok
The default `<CartLink>` renders an `<a>` tag that navigates to the Commerce Layer hosted cart application when clicked.
const Default = () => <Wrapper>
    <CartLink label="View cart" className="text-blue-600 underline hover:text-blue-800" />
</Wrapper>;
Mini cart trigger story ok
Set `type="mini"` so clicking the link publishes the `"open-cart"` event instead of navigating. A `<HostedCart type="mini">` on the same page listens for this event and opens the slide-in panel.
const MiniCartTrigger = () => {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <Wrapper>
      <CartLink
        type="mini"
        label="Open mini cart"
        className="px-4 py-2 bg-black text-white rounded text-sm"
      />
      <HostedCart type="mini" open={isOpen} handleOpen={() => setIsOpen((o) => !o)} />
    </Wrapper>
  )
};
Children props (render prop) story ok
Use the `children` render prop to fully control the trigger element. The `href` and `handleClick` props are provided by `CartLink` and wire up navigation automatically.
const ChildrenProps = () => (
  <Wrapper>
    <CartLink target="_blank">
      {({ href, handleClick, orderId }) => (
        <a
          href={href}
          onClick={handleClick}
          className="inline-flex items-center gap-2 rounded bg-black px-4 py-2 text-sm text-white hover:bg-gray-800"
        >
          🛒 Cart{orderId != null ? ` — order ${orderId}` : ""}
        </a>
      )}
    </CartLink>
  </Wrapper>
);

CheckoutLink

components-orders-checkoutlink · ./src/stories/orders/CheckoutLink.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CheckoutLink, CommerceLayer, Order, OrderStorage as OrderStorageHelper } from "@commercelayer/react-components";
Default — hosted checkout story ok
const Default = () => <Wrapper>
    <CheckoutLink
        label="Go to checkout"
        className="text-blue-600 underline hover:text-blue-800"
        target="_blank" />
</Wrapper>;
Using order checkout_url story ok
const WithOrderCheckoutUrl = () => <Wrapper>
    <CheckoutLink
        label="Checkout via order URL"
        hostedCheckout={false}
        className="text-blue-600 underline hover:text-blue-800" />
</Wrapper>;
Children props (render prop) story ok
Use the `children` render prop to fully control the rendered element. The `href` and `handleClick` props are provided by the component and wire up the organization-config-aware navigation automatically.
const ChildrenProps = () => (
  <Wrapper>
    <CheckoutLink>
      {({ href, handleClick }) => (
        <a
          href={href}
          onClick={handleClick}
          className="inline-flex items-center gap-2 rounded bg-black px-4 py-2 text-sm text-white hover:bg-gray-800"
        >
          Proceed to checkout →
        </a>
      )}
    </CheckoutLink>
  </Wrapper>
);

HostedCart

components-cart-hostedcart · ./src/stories/cart/HostedCart.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, HostedCart, Order, OrderStorage as OrderStorageHelper } from "@commercelayer/react-components";
Default — inline cart story ok
The default inline cart renders an `<iframe>` that fills the container width. The iframe height is managed automatically by `iframe-resizer`.
const Default = () => <Wrapper>
    <HostedCart />
</Wrapper>;
Custom domain story ok
Pass `customDomain` to load a self-hosted or forked cart application instead of the default Commerce Layer hosted micro-frontend.
const CustomDomain = () => <Wrapper>
    <HostedCart customDomain="cart.my-store.com" />
</Wrapper>;

HostedCart

components-cart-minicart · ./src/stories/cart/MiniCart.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import {
    AddToCartButton,
    CartLink,
    CommerceLayer,
    HostedCart,
    Order,
    OrderStorage as OrderStorageHelper,
} from "@commercelayer/react-components";
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
Mini cart story ok
Controlled mini cart: `open` and `handleOpen` are wired to local state so the panel can be opened with the button and closed by clicking the overlay or the close icon inside the cart iframe.
const Default = () => {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <Wrapper>
      <CartLink
        type="mini"
        label="Open mini cart"
        className="px-4 py-2 bg-black text-white rounded text-sm"
      />
      <HostedCart type="mini" open={isOpen} handleOpen={() => setIsOpen((o) => !o)} />
    </Wrapper>
  )
};
Auto-open on add to cart story ok
When `openAdd` is `true` the panel opens automatically after `<AddToCartButton>` successfully adds an item. The `"open-cart"` event is published internally by `AddToCartButton` on success.
const OpenOnAdd = () => <Wrapper>
    <AddToCartButton
        skuCode="SWEATWCX000000FFFFFFXSXX"
        label="Add to cart"
        quantity="1"
        className="px-4 py-2 bg-black text-white rounded text-sm disabled:opacity-50" />
    <HostedCart type="mini" openAdd />
</Wrapper>;

Order

components-orders-order · ./src/stories/orders/Order.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import {
    CommerceLayer,
    DiscountAmount,
    Order,
    OrderNumber,
    ShippingAmount,
    SubTotalAmount,
    TaxesAmount,
    TotalAmount,
} from "@commercelayer/react-components";
Order — display order details story ok
const OrderStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Order orderId="KaeheROdbp">
      <div style={{ display: "grid", gap: 8, minWidth: 240 }}>
        <div>
          Order #<OrderNumber />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Subtotal</span>
          <SubTotalAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Discount</span>
          <DiscountAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Shipping</span>
          <ShippingAmount />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between" }}>
          <span>Taxes</span>
          <TaxesAmount />
        </div>
        <hr />
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            fontWeight: "bold",
          }}
        >
          <span>Total</span>
          <TotalAmount />
        </div>
      </div>
    </Order>
  </CommerceLayer>
);
Order — with fetchOrder callback story ok
const OrderWithCallbackStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Order
      orderId="KaeheROdbp"
      fetchOrder={(order) => {
        console.log("fetchOrder: ", order)
      }}
    >
      <div>
        Order #<OrderNumber />
      </div>
      <div>
        Total: <TotalAmount />
      </div>
    </Order>
  </CommerceLayer>
);

OrderContainer

components-orders-ordercontainer · ./src/stories/orders/OrderContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, OrderContainer, OrderNumber, TotalAmount } from "@commercelayer/react-components";
OrderContainer — display order details story ok
const OrderContainerStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <OrderContainer orderId="KaeheROdbp">
      <div>
        Order #<OrderNumber />
      </div>
      <div>
        Total: <TotalAmount />
      </div>
    </OrderContainer>
  </CommerceLayer>
);

Price

components-prices-price · ./src/stories/prices/prices.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Price } from "@commercelayer/react-components";
Price — children render prop story ok
const RenderPropStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Price skuCode="POST6191FFFFFF000000XXXX">
      {({ prices, loading }) => {
        if (loading) return <span style={{ color: "#999" }}>Loading…</span>
        if (prices.length === 0) return <span style={{ color: "red" }}>No price available</span>
        const [p] = prices
        return (
          <div>
            <strong style={{ fontSize: "1.25rem" }}>{p.formatted_amount}</strong>
            {p.formatted_compare_at_amount != null && (
              <s style={{ marginLeft: 8, color: "#999" }}>{p.formatted_compare_at_amount}</s>
            )}
          </div>
        )
      }}
    </Price>
  </CommerceLayer>
);
Price — standalone story ok
const StandalonePrice = () => (
  <CommerceLayer accessToken="my-access-token">
    <div style={{ display: "grid", gap: 12 }}>
      <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
        <span style={{ width: 240, fontSize: "0.85rem", color: "#666" }}>
          POST6191FFFFFF000000XXXX
        </span>
        <Price
          skuCode="POST6191FFFFFF000000XXXX"
          style={{ fontWeight: "bold" }}
          loader={<span style={{ color: "#bbb", fontSize: "0.8rem" }}>…</span>}
        />
      </div>
      <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
        <span style={{ width: 240, fontSize: "0.85rem", color: "#666" }}>
          POLOMXXX000000FFFFFFLXXX
        </span>
        <Price
          skuCode="POLOMXXX000000FFFFFFLXXX"
          style={{ fontWeight: "bold" }}
          loader={<span style={{ color: "#bbb", fontSize: "0.8rem" }}>…</span>}
        />
      </div>
    </div>
  </CommerceLayer>
);

PricesContainer

components-prices-pricescontainer · ./src/stories/prices/PricesContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Price, PricesContainer } from "@commercelayer/react-components";
PricesContainer — single SKU story ok
const SingleSkuStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer skuCode="POST6191FFFFFF000000XXXX">
      <Price
        style={{ fontWeight: "bold", fontSize: "1.25rem" }}
        compareClassName="line-through ml-2"
      />
    </PricesContainer>
  </CommerceLayer>
);
PricesContainer — batched (single API request) story ok
const BatchedPricesStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer>
      <div style={{ display: "grid", gap: 12 }}>
        <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
          <span style={{ width: 220, fontSize: "0.85rem", color: "#666" }}>
            POST6191FFFFFF000000XXXX
          </span>
          <Price skuCode="POST6191FFFFFF000000XXXX" style={{ fontWeight: "bold" }} />
        </div>
        <div style={{ display: "flex", gap: 16, alignItems: "center" }}>
          <span style={{ width: 220, fontSize: "0.85rem", color: "#666" }}>
            POLOMXXX000000FFFFFFLXXX
          </span>
          <Price skuCode="POLOMXXX000000FFFFFFLXXX" style={{ fontWeight: "bold" }} />
        </div>
      </div>
    </PricesContainer>
  </CommerceLayer>
);
PricesContainer — with filters story ok
const WithFiltersStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <PricesContainer skuCode="POST6191FFFFFF000000XXXX" filters={{ currency_code_eq: "EUR" }}>
      <Price style={{ fontWeight: "bold" }} />
    </PricesContainer>
  </CommerceLayer>
);

Sku

components-skus-sku · ./src/stories/skus/Sku.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
Sku — standalone (no container) story ok
const StandaloneSkuStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <Sku skuCode="TSHIRTWS000000FFFFFFLXXX">
      <div style={{ marginBottom: 12 }}>
        <SkuField attribute="name" tagElement="h3" />
        <SkuField attribute="code" tagElement="p" />
      </div>
    </Sku>
    <Sku skuCode="TSHIRTWKFFFFFF000000MXXX">
      <div style={{ marginBottom: 12 }}>
        <SkuField attribute="name" tagElement="h3" />
        <SkuField attribute="code" tagElement="p" />
      </div>
    </Sku>
  </CommerceLayer>
);

SkuField

components-skus-skufield · ./src/stories/skus/SkusField.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, Sku, SkuField } from "@commercelayer/react-components";
SkuField — text attribute story ok
const Default = () => <Wrapper>
    <SkuField attribute="name" tagElement="div" />
</Wrapper>;
SkuField — image_url as <img> story ok
const SkuImageAsImgTag = () => <Wrapper>
    <SkuField attribute="image_url" tagElement="img" width={100} />
</Wrapper>;
SkuField — children render prop story ok
Access the raw attribute value through the children render prop. Useful for custom rendering — e.g. iterating over `metadata` JSON.
const ChildrenProps = () => (
  <CommerceLayer accessToken="my-access-token" endpoint="https://demo-store.commercelayer.io">
    <Sku skuCode="5PANECAP9D9CA1FFFFFFXXXX">
      <SkuField attribute="metadata" tagElement="div">
        {(childrenProps: any) => (
          <pre style={{ fontSize: "0.75rem" }}>{JSON.stringify(childrenProps, null, 2)}</pre>
        )}
      </SkuField>
    </Sku>
  </CommerceLayer>
);

SkuList

components-skus-skulist · ./src/stories/skus/SkuList.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, Skus } from "@commercelayer/react-components";
SkuList — standalone (no container) story ok
const StandaloneSkuList = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuList id="yZjQIDxrly" params={{ fields: { skus: ["code", "name"] } }}>
      <Skus>
        <div style={{ marginBottom: 12 }}>
          <SkuField attribute="name" tagElement="h3" />
          <SkuField attribute="code" tagElement="p" />
        </div>
      </Skus>
    </SkuList>
  </CommerceLayer>
);

SkuListsContainer

components-skus-skulistscontainer · ./src/stories/skus/SkuListsContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, SkuListsContainer, Skus } from "@commercelayer/react-components";
SkuListsContainer — list items story ok
const SkuListsContainerStory = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuListsContainer params={{ fields: { skus: ["code", "name"] } }}>
      <SkuList id="yZjQIDxrly">
        <Skus>
          <div style={{ marginBottom: 12 }}>
            <SkuField attribute="name" tagElement="h3" />
            <SkuField attribute="code" tagElement="p" />
          </div>
        </Skus>
      </SkuList>
    </SkuListsContainer>
  </CommerceLayer>
);

Skus

components-skus-skus · ./src/stories/skus/skus.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, SkuList, Skus } from "@commercelayer/react-components";
Skus — inside SkuList story ok
const Default = () => (
  <CommerceLayer accessToken="my-access-token">
    <SkuList id="yZjQIDxrly" params={{ fields: { skus: ["code", "name"] } }}>
      <Skus>
        <div style={{ marginBottom: 12 }}>
          <SkuField attribute="name" tagElement="h3" />
          <SkuField attribute="code" tagElement="p" />
        </div>
      </Skus>
    </SkuList>
  </CommerceLayer>
);

SkusContainer

components-skus-skuscontainer · ./src/stories/skus/SkusContainer.stories.tsx
Prop type error
File: /opt/build/repo/packages/react-components/dist/index.cjs
react-docgen-typescript did not return any component docs for this file.
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ArgTypes, Canvas, Source } from "@storybook/addon-docs/blocks";
import { CommerceLayer, SkuField, Skus, SkusContainer } from "@commercelayer/react-components";
SkusContainer — name and code story ok
const Default = () => <CommerceLayer
    accessToken="my-access-token"
    endpoint="https://demo-store.commercelayer.io">
    <SkusContainer skus={["POLOMXXX000000FFFFFFLXXX", "CROPTOPWFFFFFF000000XSXX"]}>
        <Skus>
            <div style={{ marginBottom: 12 }}>
                <SkuField attribute="name" tagElement="h3" />
                <SkuField attribute="code" tagElement="p" />
            </div>
        </Skus>
    </SkusContainer>
</CommerceLayer>;
SkusContainer — with query params story ok
const WithQueryParams = () => <CommerceLayer
    accessToken="my-access-token"
    endpoint="https://demo-store.commercelayer.io">
    <SkusContainer
        skus={["POLOMXXX000000FFFFFFLXXX", "CROPTOPWFFFFFF000000XSXX"]}
        queryParams={{
          pageSize: 25,
          pageNumber: 1,
          fields: ["name", "description", "image_url", "reference"],
          sort: { name: "asc" },
        }}>
        <Skus>
            <div style={{ marginBottom: 12 }}>
                <SkuField attribute="name" tagElement="h3" />
                <SkuField attribute="code" tagElement="p" />
            </div>
        </Skus>
    </SkusContainer>
</CommerceLayer>;

Unattached Docs

Getting Started/Introduction

getting-started-introduction--docs · ./src/stories/getting-started/001.introduction.mdx
![App Element splashscreen](welcome-hero.png) A collection of reusable React components th...
import { Meta, Source } from '@storybook/addon-docs/blocks';

    <Meta title="Getting Started/Introduction"></Meta>

![App Element splashscreen](welcome-hero.png)

A collection of reusable React components that makes it super fast and simple to build your own custom commerce UI, leveraging Commerce Layer API.

Under the hood, our React components are built on top of [Commerce Layer JS SDK](https://github.com/commercelayer/commercelayer-sdk) — feel free to use it if you want to develop your custom ones.


## Installation

This library is [open sourced](https://github.com/commercelayer/commercelayer-react-components/) and served as [npm package](https://www.npmjs.com/package/@commercelayer/react-components) and need to be installed as dependency inside your project.


    <Source
          language="bash"
          dark
          code={`
// npm
npm install @commercelayer/react-components

// yarn
yarn add @commercelayer/react-components

// pnpm
pnpm add @commercelayer/react-components
`}
        />


## Import components into your project

You can use ES6 named import with every single component you plan to use (in addition to `CommerceLayer` one), as follow:

    <Source
          language="jsx"
          dark
          code={`
import { CommerceLayer, ...otherComponents } from '@commercelayer/react-components'
`}
        />

But you can also leverage treeshaking by importing only the components you need from its folder using either default or named export, as follow:

    <Source
          language="jsx"
          dark
          code={`
import OrderContainer from '@commercelayer/react-components/orders/OrderContainer'
// or
import { OrderContainer } from '@commercelayer/react-components/orders/OrderContainer'
`}
        />

Getting Started/Authentication

getting-started-authentication--docs · ./src/stories/getting-started/002.authentication.mdx
# Authentication To get started with **Commerce Layer React Components** you need get the ...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Authentication"></Meta>

# Authentication

To get started with **Commerce Layer React Components** you need get the credentials that will allow you to perform the API calls they wrap.

All requests to Commerce Layer API must be authenticated with an [OAuth2](https://oauth.net/2/) bearer token. 
Hence, to use these components, you need to get a valid access token. 


## Getting an access token
<span title="Important note" type="warning">
If you are new to Commerce Layer, we suggest you to read the [Overview of Commerce Layer's OAuth 2.0](https://docs.commercelayer.io/core/applications) guide.
</span>

There are many ways to get an access token and the one you choose depends on your specific needs.

You can get an access token by using one of the following methods:
- [API/OAuth requests](https://docs.commercelayer.io/core/authentication/client-credentials#getting-an-access-token) (i.e. `curl` or `postman`)
- [Commerce Layer CLI](https://github.com/commercelayer/commercelayer-cli)
- [Commerce Layer JS Auth Library](https://github.com/commercelayer/commercelayer-js-auth)

<span title="Suggestion" type="info">
If you want to retrieve the access token from the **command line**, we suggest you to use the [Commerce Layer CLI](https://github.com/commercelayer/commercelayer-cli) 
using the `commercelayer application:login` command ([view example](https://github.com/commercelayer/commercelayer-cli/blob/main/docs/applications.md#commercelayer-applicationslogin)), 
followed by `commercelayer application:token`

<hr />
Otherwise, if you need to get it from a **web application**, you can use the Commerce Layer JS Auth library that works both in the browser and in Node.js environments.
</span>




## Configure the `CommerceLayer` component
Once you got it, you can pass it as prop to the `CommerceLayer` component, as follow:

<Source
  language="jsx"
  dark
  code={`
import { CommerceLayer } from '@commercelayer/react-components'

const App = () => (
  <CommerceLayer accessToken="your-access-token">
    {/* ... child components */}
  </CommerceLayer>
)
`}
/>


This token will be used to authorize the API calls of all its child components. 
That's why the presence of (at least) one `CommerceLayer` component is mandatory — it must wrap every other component you need to use.

<span title="Multiples tokens" type="info">
In case you need to fetch data with different tokens (i.e. from different organizations or using apps with different roles and permissions) 
— nothing prevents you from putting as many `<CommerceLayer>` components you want in the same page.
</span>

Getting Started/Micro frontends

getting-started-micro-frontends--docs · ./src/stories/getting-started/003.microfrontends.mdx
# Micro frontends We use **Commerce Layer React Components** library in our official open ...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Micro frontends"></Meta>

# Micro frontends

We use **Commerce Layer React Components** library in our official open sourced hosted applications. 

Feel free to check them out and see how it works in a real world application.


|Application|Description|Source|
|:-----------|:-----------|:----|
| Checkout | Checkout application that you can integrate with just a single link or use as an open-source reference for your projects. | [GitHub](https://github.com/commercelayer/mfe-checkout)
| Cart | Shopping cart application that you can integrate with just a single link or use as an open-source reference for your projects. | [GitHub](https://github.com/commercelayer/mfe-cart)
| My account | Customer portal application with personal account information and management that you can integrate with just a single link or use as an open-source reference for your projects. | [GitHub](https://github.com/commercelayer/mfe-my-account)
| Microstore | Production-ready, self-contained store. Each microstore will be accessible at a unique URL and configurable via URL query strings, with no development required. | [GitHub](https://github.com/commercelayer/mfe-microstore)

Getting Started/Styling

getting-started-styling--docs · ./src/stories/getting-started/004.styling.mdx
# Styling the components This library does not provide any styling. They return simple htm...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Styling"></Meta>

# Styling the components

This library does not provide any styling. They return simple html/jsx tags filled with fetched data. 

**<u>It is up to you to style the components as you want</u>**.

Almost all components expose a `className` prop that allows you to add your own css classes.
Some components that renders multiple elements also expose other props to add classes to each specific elements.

<span title="CSS in this documentation" type="info">
All the examples in this documentation use [Tailwind CSS](https://tailwindcss.com/) to demostrate how the components can be styled.
</span>

Getting Started/Containers

getting-started-containers--docs · ./src/stories/getting-started/005.containers.mdx
# Containers Getting used to the components hierarchy is important to understand how to us...
import { Meta, Source } from '@storybook/addon-docs/blocks'; 

<Meta title="Getting Started/Containers"></Meta>

# Containers

Getting used to the components hierarchy is important to understand how to use this library.

All components need to be wrapped inside the main `<CommerceLayer>` context that handles the authentication with the API layer.
**It needs to be placed at the top of the application**.

---

## Deprecation notice

<span title="Deprecation" type="warning">
Container components (e.g. `PricesContainer`) are **deprecated** and will be removed in a future major release.
Components are being migrated to work **standalone** — drop them directly under `<CommerceLayer>` with no wrapper needed.
Batching, caching and deduplication are handled automatically at the module level.
</span>

Previously, components like `<Price>` required a dedicated container to fetch and share data:

<Source
  language="jsx"
  dark
  code={`// ❌ Old pattern — PricesContainer is deprecated
<CommerceLayer accessToken="...">
  <PricesContainer skuCode="MY-SKU">
    <Price />
  </PricesContainer>
</CommerceLayer>`}
/>

Now components work standalone — multiple instances are automatically batched into a single API request via a 50 ms debounce:

<Source
  language="jsx"
  dark
  code={`// ✅ New pattern — no container needed
<CommerceLayer accessToken="...">
  <Price skuCode="SKU-A" />
  <Price skuCode="SKU-B" />
  <Price skuCode="SKU-C" />
</CommerceLayer>`}
/>

---

## Hierarchy

Each component documented in the Components section of this guide highlights a list of **Requirements** and **Children** that are needed to make it work.

Example:

<span title="Requirements" type="warning">
Must be a child of `<CommerceLayer>` component.
</span>


<span title="Children" type="info">
`<OrderNumber>`
`<TotalAmount>`
`<PlaceOrderButton>`
</span>

Getting Started/Core package

getting-started-core-package--docs · ./src/stories/getting-started/006.core.mdx
# Core package The `@commercelayer/core-components` package is a collection of **low-level...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Core package"></Meta>

# Core package

The `@commercelayer/core-components` package is a collection of **low-level async functions** that wrap the [Commerce Layer SDK](https://github.com/commercelayer/commercelayer-sdk).

It is the foundation layer used internally by the `@commercelayer/react-hooks-components` package and by the React components. You can use it directly if you need to fetch or mutate Commerce Layer resources outside of a React component.

<span type="info">
This package has no React dependency — it can be used in any JavaScript/TypeScript environment (Node.js, edge functions, plain scripts, etc.).
</span>

## Installation

The package is published to npm as part of this monorepo and listed as a workspace dependency. To install it in a standalone project:

<Source
  language="bash"
  dark
  code={`
npm install @commercelayer/core-components
# or
pnpm add @commercelayer/core-components
`}
/>

## All exports

| Function | Description |
|---|---|
| `getAccessToken` | Retrieve an OAuth access token via `@commercelayer/js-auth` |
| `getSkus` | Fetch a paginated list of SKUs |
| `retrieveSku` | Fetch a single SKU by ID |
| `updateSku` | Update a single SKU by ID |
| `getPrices` | Fetch a paginated list of prices |
| `retrievePrice` | Fetch a single price by ID |
| `updatePrice` | Update a single price |
| `getSkuAvailability` | Fetch availability for a given SKU code or ID |
| `getSkuLists` | Fetch a paginated list of SKU lists |
| `retrieveSkuList` | Fetch a single SKU list by ID (with optional includes) |

## Function signature

Every function follows the same pattern:

<Source
  language="typescript"
  dark
  code={`
import { getSkus } from '@commercelayer/core-components'

const skus = await getSkus({
  accessToken: 'your-access-token',
  params: {
    filters: { code_start: 'TSHIRT' },
    pageSize: 10,
  },
})
`}
/>

The first argument is always an object with:

| Property | Type | Required | Description |
|---|---|---|---|
| `accessToken` | `string` | ✅ | Commerce Layer API access token |
| `params` | `QueryParamsList<Resource>` or `QueryParamsRetrieve<Resource>` | ❌ | Optional SDK query params (filters, fields, include, pagination) |
| `options` | `ResourcesConfig` | ❌ | Optional SDK request configuration |

## Examples

### Authentication

<Source
  language="typescript"
  dark
  code={`
import { getAccessToken } from '@commercelayer/core-components'

const token = await getAccessToken({
  grantType: 'client_credentials',
  config: {
    clientId: 'your-client-id',
    slug: 'your-org-slug',
    scope: 'market:id:1234',
  },
})

console.log(token.accessToken)
`}
/>

### Fetch a filtered list of SKUs

<Source
  language="typescript"
  dark
  code={`
import { getSkus } from '@commercelayer/core-components'

const result = await getSkus({
  accessToken,
  params: {
    filters: { code_in: 'TSHIRTWS000000FFFFFFLXXX,TSHIRTWKFFFFFF000000MXXX' },
    fields: { skus: ['name', 'code', 'image_url'] },
  },
})

for (const sku of result) {
  console.log(sku.code, sku.name)
}
`}
/>

### Retrieve a SKU list with included SKUs

<Source
  language="typescript"
  dark
  code={`
import { retrieveSkuList } from '@commercelayer/core-components'

const skuList = await retrieveSkuList({
  accessToken,
  id: 'yZjQIDxrly',
  params: {
    include: ['skus'],
    fields: { skus: ['name', 'code', 'image_url'] },
  },
})

console.log(skuList.skus)
`}
/>

Getting Started/Hooks package

getting-started-hooks-package--docs · ./src/stories/getting-started/007.hooks.mdx
# Hooks package The `@commercelayer/react-hooks-components` package provides **SWR-based R...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Hooks package"></Meta>

# Hooks package

The `@commercelayer/react-hooks-components` package provides **SWR-based React hooks** built on top of the `@commercelayer/core-components` package.

These hooks handle caching, deduplication, loading states, and error handling automatically. They are used internally by the React components in this library and are available for direct use if you want to build custom UI on top of Commerce Layer data.

<span type="info">
This package requires React 19 and depends on `swr` for data fetching and caching.
</span>

## Installation

<Source
  language="bash"
  dark
  code={`
npm install @commercelayer/react-hooks-components
# or
pnpm add @commercelayer/react-hooks-components
`}
/>

## All exports

| Hook | Description |
|---|---|
| `useAddressForm` | Billing and shipping address form state, and saving it to the order |
| `useAvailability` | Fetch availability for a SKU code or ID |
| `useCustomer` | Fetch a customer with their addresses, payment sources and orders |
| `useGiftCards` | Fetch, create and update gift cards |
| `useInStockSubscriptions` | Subscribe a customer to a SKU coming back in stock |
| `useLineItems` | Fetch the order's line items, and update or delete them |
| `useOrder` | Fetch, create and update an order |
| `usePrices` | Fetch, retrieve, and update prices |
| `useShipments` | Fetch the order's shipments and set a shipping method |
| `useSkuList` | Retrieve a single SKU list by ID |
| `useSkuLists` | Fetch and retrieve SKU lists |
| `useSkus` | Fetch, retrieve, and update SKUs |

## Return shape

Every hook returns a consistent object shape:

| Property | Type | Description |
|---|---|---|
| `data` (e.g. `skus`, `prices`) | `Resource[]` | The fetched list of resources. Empty array until loaded. |
| `isLoading` | `boolean` | `true` while the first fetch is in-flight |
| `isValidating` | `boolean` | `true` during any background revalidation |
| `error` | `string \| null` | Error message if the last request failed |
| `fetchXxx` | `(params?) => void` | Triggers the list fetch. Calling it again with new params re-fetches. |
| `retrieveXxx` | `(id) => Promise<Resource>` | Fetches a single resource by ID |
| `updateXxx` | `(resource) => Promise<Resource>` | Mutates a resource and updates the local cache |
| `clearXxx` | `() => void` | Resets the cache and stops auto-revalidation |
| `mutate` | `KeyedMutator<Resource[]>` | Direct access to the underlying SWR mutate function |

## Caching behaviour

All hooks use [SWR](https://swr.vercel.app/) with `revalidateOnFocus: false` and `revalidateOnReconnect: false` by default. This means:

- Data is cached per `[resource, action, accessToken, params]` key
- A second call with the same arguments is a no-op (served from cache)
- Calling `fetchXxx` with different params triggers a new request

## Examples

### useSkus — fetch and render a filtered list

<Source
  language="tsx"
  dark
  code={`
import { useSkus } from '@commercelayer/react-hooks-components'

function SkuList({ accessToken }: { accessToken: string }) {
  const { skus, isLoading, fetchSkus } = useSkus(accessToken)

  useEffect(() => {
    fetchSkus({
      filters: { code_in: 'TSHIRTWS000000FFFFFFLXXX,TSHIRTWKFFFFFF000000MXXX' },
      fields: { skus: ['name', 'code', 'image_url'] },
    })
  }, [])

  if (isLoading) return <p>Loading…</p>

  return (
    <ul>
      {skus.map((sku) => (
        <li key={sku.id}>{sku.name} — {sku.code}</li>
      ))}
    </ul>
  )
}
`}
/>

### useSkuLists — retrieve a SKU list with included SKUs

<Source
  language="tsx"
  dark
  code={`
import { useSkuLists } from '@commercelayer/react-hooks-components'

function SkuListItems({ accessToken }: { accessToken: string }) {
  const { retrieveSkuList } = useSkuLists(accessToken)
  const [skus, setSkus] = useState([])

  useEffect(() => {
    retrieveSkuList('yZjQIDxrly', {
      include: ['skus'],
      fields: { skus: ['name', 'code'] },
    }).then((list) => setSkus(list?.skus ?? []))
  }, [])

  return (
    <ul>
      {skus.map((sku) => (
        <li key={sku.id}>{sku.name}</li>
      ))}
    </ul>
  )
}
`}
/>

### usePrices — fetch prices for a set of SKU codes

<Source
  language="tsx"
  dark
  code={`
import { usePrices } from '@commercelayer/react-hooks-components'

function PriceList({ accessToken }: { accessToken: string }) {
  const { prices, isLoading, fetchPrices } = usePrices(accessToken)

  useEffect(() => {
    fetchPrices({ filters: { sku_code_in: 'TSHIRTWS000000FFFFFFLXXX' } })
  }, [])

  if (isLoading) return <p>Loading…</p>

  return (
    <ul>
      {prices.map((price) => (
        <li key={price.id}>{price.sku_code} — {price.formatted_amount}</li>
      ))}
    </ul>
  )
}
`}
/>

### useAvailability — check stock for a SKU

<Source
  language="tsx"
  dark
  code={`
import { useAvailability } from '@commercelayer/react-hooks-components'

function StockBadge({ accessToken, skuCode }: { accessToken: string; skuCode: string }) {
  const { quantity, isLoading, fetchAvailability } = useAvailability(accessToken)

  useEffect(() => {
    fetchAvailability({ skuCode })
  }, [skuCode])

  if (isLoading) return null

  return <span>{quantity != null && quantity > 0 ? 'In stock' : 'Out of stock'}</span>
}
`}
/>

Getting Started/Upgrading from v4

getting-started-upgrading-from-v4--docs · ./src/stories/getting-started/008.upgrading-from-v4.mdx
# Upgrading from v4 This guide covers the move from `@commercelayer/react-components` **v4...
import { Meta, Source } from '@storybook/addon-docs/blocks';

<Meta title="Getting Started/Upgrading from v4"></Meta>

# Upgrading from v4

This guide covers the move from `@commercelayer/react-components` **v4** to **v5**.

Most of the upgrade is mechanical. The v5 root barrel is a strict superset of v4's: every name v4 exported **from the package root** is still exported, and the deprecated container components keep working. What v5 removed is the 20 subpath entry points — and a few components were public only through those, so check section 3 before you start. Past that, you can upgrade in two stages: get the app running on v5 first, then migrate the deprecated patterns at your own pace.

There are, however, four changes that **will** break a v4 app and need to be handled up front. Their headings are marked **(breaking)**.

---

## At a glance

| | v4.29.7 | v5.0.0 |
| --- | --- | --- |
| `react` peer range | `>=18.0.0` | `>=19.0.0` |
| Sibling packages | — | `@commercelayer/core-components`, `@commercelayer/react-hooks-components` |
| Build output | `lib/cjs` + `lib/esm` | `dist` (both CJS and ESM) |
| Subpath exports | 20 (`./orders/*`, `./hooks/*`, …) | none — root entry only |
| `@commercelayer/sdk` | `^6.46.0` | `8.0.0-beta.11` |
| `<CommerceLayer>` props | `accessToken`, `endpoint`, `domain` | `accessToken`, `interceptors` |
| Container components | required | deprecated, standalone components preferred |

---

## 1. Update the dependency

<Source
  language="bash"
  dark
  code={`# npm
npm install @commercelayer/react-components@5

# yarn
yarn add @commercelayer/react-components@5

# pnpm
pnpm add @commercelayer/react-components@5`}
/>

v5 splits the library into three packages. `@commercelayer/core-components` (the framework-agnostic data layer) and `@commercelayer/react-hooks-components` (the SWR-based hooks) are regular dependencies of `@commercelayer/react-components`, so your package manager installs them for you. You do **not** need to add them to your `package.json`.

<span title="Watch out" type="warning">
If your `package.json` already lists `@commercelayer/core-components` or `@commercelayer/react-hooks-components` as **direct** dependencies, a direct entry shadows the transitive one: bumping `@commercelayer/react-components` alone will leave the siblings pinned at their old version, and you get two incompatible copies in the same tree.
</span>

Remove the direct entries and let them resolve through the library:

<Source
  language="bash"
  dark
  code={`pnpm remove @commercelayer/core-components @commercelayer/react-hooks-components
pnpm install`}
/>

Only declare them directly if you import from them yourself — and then keep their version in lockstep with `@commercelayer/react-components`.

---

## 2. React 19 (breaking)

The peer range moved from `>=18.0.0` to `>=19.0.0`. v5 is compiled with the React Compiler targeting React 19, so React 18 is not supported.

<Source
  language="bash"
  dark
  code={`npm install react@19 react-dom@19`}
/>

The published bundle already carries a `"use client"` banner, so in the Next.js App Router you don't need to add the directive yourself when importing these components.

---

## 3. Deep imports are gone (breaking)

v4 exposed 20 subpath export patterns, which let you import a single component straight from its file. v5 publishes a **single root entry**, so every import has to come from the package root.

<Source
  language="jsx"
  dark
  code={`// ❌ v4 — deep import, no longer resolvable
import { Price } from '@commercelayer/react-components/prices/Price'
import { useOrderContainer } from '@commercelayer/react-components/hooks/useOrderContainer'

// ✅ v5 — everything from the root
import { Price, useOrderContainer } from '@commercelayer/react-components'`}
/>

Both CJS and ESM builds are still shipped, so `require()` keeps working at the root entry. Only the subpaths are affected.

One component changed module while keeping its name: `DeliveryLeadTime` moved from the `skus` folder to `shipping_methods`. If you imported it from the root, nothing changes.

### Check the names, don't assume they moved

The root barrel covers everything v4 exported from the root, but some modules were public *only* through a subpath and have no root equivalent. The `context/*`, `utils/*` and `component_utils/*` trees are internal and were never intended as public API. `gift_cards/GiftCardRecipientInput` was removed from the source altogether.

The individual payment provider components — `payment_source/AdyenPayment`, `StripePayment`, `PaypalPayment` and the rest — are also internal now. `<PaymentMethod>` selects the right one from the payment source type, so configure it through the `config` prop rather than rendering a provider yourself:

<Source
  language="jsx"
  dark
  code={`// ❌ v4 — rendering a provider directly
import AdyenPayment from '@commercelayer/react-components/payment_source/AdyenPayment'

// ✅ v5 — configure it through PaymentMethod
import { PaymentMethod, type PaymentMethodConfig } from '@commercelayer/react-components'

const config: PaymentMethodConfig = { adyenPayment: { … } }

<PaymentMethod config={config} />`}
/>

Grep your own imports for `@commercelayer/react-components/` and check each name against the root barrel rather than assuming it simply moved. If a component you relied on is missing from the root, please open an issue: several were left out of the barrel unintentionally when the subpaths were removed, and those are bugs we want to fix rather than deliberate removals.

---

## 4. `<CommerceLayer>` loses `endpoint` and `domain` (breaking)

In v4 you could pass an explicit `endpoint`, or a `domain` the endpoint was built from. Both props are gone. v5 derives the organization from the access token itself, so the token is all the provider needs.

<Source
  language="jsx"
  dark
  code={`// ❌ v4
<CommerceLayer
  accessToken={accessToken}
  endpoint="https://yourdomain.commercelayer.io"
>
  {children}
</CommerceLayer>

// ✅ v5
<CommerceLayer accessToken={accessToken}>
  {children}
</CommerceLayer>`}
/>

If you were passing `domain` to reach a non-default environment, that now belongs to how the token is issued rather than to this component — see <a href="/?path=/docs/getting-started-authentication--docs">Authentication</a>.

In its place there is a new optional `interceptors` prop, to attach request and response interceptors to the underlying SDK client:

<Source
  language="jsx"
  dark
  code={`<CommerceLayer
  accessToken={accessToken}
  interceptors={{
    response: {
      onSuccess: (response) => response,
      onFailure: (error) => { throw error }
    }
  }}
>
  {children}
</CommerceLayer>`}
/>

---

## 5. Migrate away from containers

This is the part you can postpone. Container components still work in v5 — they forward to their replacement and log a deprecation warning in development builds only. They will be removed in the next major version.

The idea behind the change is described in <a href="/?path=/docs/getting-started-containers--docs">Containers</a>: components fetch their own data and batch the requests at module level, so the wrapper that existed only to share a fetch is no longer needed.

### Straight renames

Same props, shorter name:

| v4 (deprecated) | v5 |
| --- | --- |
| `<OrderContainer>` | `<Order>` |
| `<LineItemsContainer>` | `<LineItems>` |
| `<CustomerContainer>` | `<Customer>` |
| `<BillingAddressContainer>` | `<BillingAddress>` |
| `<ShippingAddressContainer>` | `<ShippingAddress>` |
| `<ShipmentsContainer>` | `<Shipments>` |
| `<InStockSubscriptionsContainer>` | `<InStockSubscriptions>` |
| `<AvailabilityContainer>` | `<Availability>` |

<Source
  language="jsx"
  dark
  code={`// ❌ v4
<OrderContainer orderId={orderId}>
  <TotalAmount />
</OrderContainer>

// ✅ v5
<Order orderId={orderId}>
  <TotalAmount />
</Order>`}
/>

### Containers that dissolve

Here the wrapper disappears and its props move onto the components that used to sit inside it.

| v4 (deprecated) | v5 |
| --- | --- |
| `<PricesContainer>` | `<Price skuCode="…" />` standalone, or the `usePrices` hook for batched prices |
| `<GiftCardContainer>` | `<GiftCard>` standalone — it manages its own context |
| `<SkusContainer>` | `<Sku skuCode="…">` standalone |
| `<SkuListsContainer>` | `<SkuList>` standalone |
| `<PaymentMethodsContainer>` | `<PaymentMethod>` standalone, with `config` passed directly |
| `<PlaceOrderContainer>` | `<PlaceOrderButton>` and `<PrivacyAndTermsCheckbox>` directly |
| `<AddressesContainer>` | `<BillingAddressForm>` and `<ShippingAddressForm>`, which take the container's props |

`<AddressesContainer>` is the one that needs the most care, because its props split across two forms:

<Source
  language="jsx"
  dark
  code={`// ❌ v4
<AddressesContainer isBusiness={isBusiness} shipToDifferentAddress={ship}>
  <BillingAddressForm>…</BillingAddressForm>
  <ShippingAddressForm>…</ShippingAddressForm>
</AddressesContainer>

// ✅ v5
<BillingAddressForm isBusiness={isBusiness} shipToDifferentAddress={ship}>…</BillingAddressForm>
<ShippingAddressForm shipToDifferentAddress={ship}>…</ShippingAddressForm>`}
/>

And `<PlaceOrderContainer>` simply goes away:

<Source
  language="jsx"
  dark
  code={`// ❌ v4
<PlaceOrderContainer>
  <PrivacyAndTermsCheckbox />
  <PlaceOrderButton label="Place order" />
</PlaceOrderContainer>

// ✅ v5
<PrivacyAndTermsCheckbox />
<PlaceOrderButton label="Place order" />`}
/>

### When the consumer is not a child

The examples above put everything in one subtree. A stepped checkout does not: the button that saves both address forms has to be their sibling, and the place-order step sits outside the payment step. The standalone components handle that — the state they share lives per order rather than in the tree, so they find each other wherever they sit.

Two things follow from that, and they are worth knowing before you hit them.

**State that your app owns, your app publishes.** `shipToDifferentAddress` is the case in point: the container used to hold it, and once it is gone the only components that could publish it are the two address forms. If your UI unmounts a form — a transition that swaps the form for a saved-address card, say — nothing publishes the flag any more. Publish it from wherever it lives in your app instead:

<Source
  language="tsx"
  dark
  code={`import { useAddressForm } from "@commercelayer/react-hooks-components"

const { setFlags } = useAddressForm({ accessToken, orderId })

useEffect(() => {
  setFlags({ shipToDifferentAddress })
}, [shipToDifferentAddress, setFlags])`}
/>

**Two editors on one order need to say so.** Instances sharing an order share their form state, which is what makes the sibling button work. If you deliberately render two independent address editors for the same order, pass `scope` to keep them apart.

<span title="Tip" type="info">
Run your app in development mode after the upgrade and watch the console: every deprecated container you are still using logs a warning naming its replacement. That list is your migration backlog.
</span>

---

## 6. Dependencies you may have relied on indirectly

v5 drops several transitive dependencies. If your own code imported them without declaring them, add them to your `package.json` explicitly:

- `lodash` — removed
- `jwt-decode` — removed; token decoding now happens inside `@commercelayer/core-components`

`@commercelayer/sdk` also jumps from `^6.46.0` to `8.0.0-beta.11`, and if you use the SDK alongside these components, **aligning your version is required, not advisory**. The SDK is a regular dependency here rather than a peer, so a consumer still on SDK 6 installs cleanly and only fails later, at typecheck, wherever an SDK-typed value crosses the boundary — an `Address` coming out of an `<AddressField>` render prop, for instance:

<Source
  language="text"
  dark
  code={`Type 'BingGeocoder' is not assignable to type 'Geocoder'.
  Types of property 'type' are incompatible.
    Type '"bing_geocoders"' is not assignable to type '"geocoders"'.`}
/>

SDK 8 adds the `BingGeocoder` variant to the nested `geocoder` union, so anything that reaches `Address` is affected — including `OrderSubscription`, through `market` → `merchant` → `address`.

---

## What's new in v5

Beyond the migration, v5 adds surface you may want to adopt:

- **`@commercelayer/core-components`** — the data layer on its own, usable without React. See <a href="/?path=/docs/getting-started-core-package--docs">Core package</a>.
- **`@commercelayer/react-hooks-components`** — SWR-based hooks with caching, deduplication and loading states. See <a href="/?path=/docs/getting-started-hooks-package--docs">Hooks package</a>.
- **`useTermsAndConditions`** — reads and updates privacy and terms acceptance, the hook behind `<PrivacyAndTermsCheckbox>`.
- **New standalone components** — `<HostedCart>`, plus the shorter names listed above.
- **`SkuAvailability`** — re-exported as a type from `@commercelayer/core-components`.

---

## Checklist

1. Bump `@commercelayer/react-components` to v5.
2. Remove any direct dependency on `core-components` or `react-hooks-components`.
3. Move to React 19.
4. Replace deep imports with root imports.
5. Drop `endpoint` and `domain` from `<CommerceLayer>`.
6. Declare any dependency you were getting transitively.
7. Run in development and clear the deprecation warnings when convenient.