cimplify
Sdk

React SDK

90+ components and 30+ hooks from `@cimplify/sdk/react`. Wrap your app in `<CimplifyProvider>`, drop in `<CataloguePage>`, ` <ProductPage>`, `<CartPage>`, `<CheckoutPage>`, or build from primitives with the data hooks.

bun add @cimplify/sdk

Provider

Construct a client once and pass it to CimplifyProvider. Wrap with CartDrawerProvider if you want a slide-over cart anywhere in the app.

components/providers.tsx
"use client";
import { useMemo, type ReactNode } from "react";
import { createCimplifyClient } from "@cimplify/sdk";
import { CimplifyProvider, CartDrawerProvider } from "@cimplify/sdk/react";

export function Providers({ children }: { children: ReactNode }) {
  const client = useMemo(
    () =>
      createCimplifyClient({
        publicKey: process.env.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY,
      }),
    [],
  );

  return (
    <CimplifyProvider client={client}>
      <CartDrawerProvider>{children}</CartDrawerProvider>
    </CimplifyProvider>
  );
}

CimplifyProvider props

PropTypeDescription
clientCimplifyClientFrom createCimplifyClient(...).
childrenReactNodeApp subtree.
onLocationChange?(loc: Location) => voidFires when setCurrentLocation is called.

Components

Full storefront pages, primitives, and selectors all live in @cimplify/sdk/react. Each is a normal React component you can compose, restyle, or eject for full control.

Page components

Full-page implementations you mount on a route.

  • <CataloguePage>
  • <ProductPage>
  • <CartPage>
  • <CheckoutPage>
  • <SearchPage>
  • <CimplifyAccount>

Cart drawer

Slide-over cart with free-shipping progress.

  • <CartDrawerProvider>
  • <CartDrawer>
  • useCartDrawer()

Cards & grids

Variant-aware product cards by industry.

  • FoodProductCard, RetailProductCard
  • WholesaleProductCard, DigitalProductCard
  • StandardServiceCard, RentalServiceCard
  • <ProductGrid>, <CategoryGrid>

Customizers

Compose into <ProductCustomizer>.

  • VariantSelector
  • AddOnSelector
  • BundleSelector
  • CompositeSelector
  • BillingPlanSelector

Primitives

Drop-in building blocks.

  • <Price>, <PriceRange>
  • <QuantitySelector>
  • <DealBanner>, <SaleBadge>
  • <DeliveryEstimate>
  • <ChatWidget>

Scheduling

For services / bookable products.

  • SlotPicker, DateSlotPicker
  • StaffPicker, ResourcePicker
  • BookingCard, BookingList
  • BookingsPage

A four-route storefront

Real Next.js App Router scaffolding. Each page is a few lines.

app/shop/page.tsx
"use client";
import { CataloguePage } from "@cimplify/sdk/react";
import { useRouter } from "next/navigation";

export default function ShopPage() {
  const router = useRouter();
  return (
    <CataloguePage
      pageSize={24}
      onProductClick={(p) => router.push(`/products/${p.slug ?? p.id}`)}
    />
  );
}
app/products/[slug]/page.tsx
"use client";
import { ProductPage } from "@cimplify/sdk/react";
import { useParams } from "next/navigation";

export default function Product() {
  const { slug } = useParams<{ slug: string }>();
  return <ProductPage productId={slug} />;
}
app/cart/page.tsx + app/checkout/page.tsx
"use client";
import { CartPage, CheckoutPage } from "@cimplify/sdk/react";
import { useRouter } from "next/navigation";

export function Cart() {
  const router = useRouter();
  return <CartPage onCheckout={() => router.push("/checkout")} />;
}

export function Checkout() {
  const router = useRouter();
  return (
    <CheckoutPage
      onComplete={(r) => router.push(`/orders/${r.order?.id}`)}
    />
  );
}

Hooks

When you want full control over layout, drive everything from hooks. Each hook returns { ..., isLoading, error, refetch } and shares a module-scoped cache that survives re-renders.

import { useProducts, useCart, useCartDrawer } from "@cimplify/sdk/react";

function FeaturedRow() {
  const { products, isLoading } = useProducts({ featured: true, limit: 6 });
  const { addItem } = useCart();
  const { open } = useCartDrawer();

  if (isLoading) return <p>Loading...</p>;
  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>
          {p.name}
          <button onClick={() => { addItem(p); open(); }}>Add</button>
        </li>
      ))}
    </ul>
  );
}

Demo mode

If publicKey is empty, the provider enters demo mode: no API calls, isReady stays false, useful for prototyping. The local mock (bunx @cimplify/sdk mock) gives you a real backend in 0 seconds.

Where next

On this page