Server Components
`@cimplify/sdk/server` is a Node-only entry for the Next.js App Router. It ships three things: a request-memoized client factory, a typed cache-tag scheme, and Server Action revalidation helpers.
Caching is Next's job. Wrap composed reads in a function with "use cache" + cacheTag(tags.X()) + cacheLife(...), and revalidate from Server Actions via revalidateProducts() and friends. The SDK doesn't try to be a caching layer of its own.
getServerClient
Returns a standard CimplifyClient wrapped in React's cache(), so every Server Component in the same request shares a single instance. Reads server env vars (CIMPLIFY_SECRET_KEY, CIMPLIFY_API_URL) with friendly defaults for the local mock.
import { unstable_cacheTag as cacheTag, unstable_cacheLife as cacheLife } from "next/cache";
import { getServerClient, tags } from "@cimplify/sdk/server";
async function getCatalogue() {
"use cache";
cacheTag(tags.products());
cacheLife("hours");
const r = await getServerClient().catalogue.getProducts({ limit: 24 });
if (!r.ok) throw new Error(r.error.message);
return r.value.items;
}
export default async function Home() {
const products = await getCatalogue();
return <ul>{products.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}Options
| Option | Type | Description |
|---|---|---|
secretKey | string | Defaults to CIMPLIFY_SECRET_KEY. |
baseUrl | string | Defaults to CIMPLIFY_API_URL. |
fetch | typeof fetch | Inject a custom fetch (e.g. for tests). |
tags: cache-tag builders
Pass these to cacheTag() on cached functions, or to next.tags on raw fetches. Tag strings are namespaced under cimplify: so they can't collide with consumer tags.
| Builder | Tag |
|---|---|
tags.products() | cimplify:products |
tags.product(id) | cimplify:product:<id> |
tags.categories() | cimplify:categories |
tags.category(id) | cimplify:category:<id> |
tags.categoryProducts(id) | cimplify:category:<id>:products |
tags.collections() | cimplify:collections |
tags.collection(id) | cimplify:collection:<id> |
tags.collectionProducts(id) | cimplify:collection:<id>:products |
tags.business() | cimplify:business |
tags.locations() | cimplify:locations |
tags.orders(customerId) | cimplify:orders:<customerId> |
tags.order(id) | cimplify:order:<id> |
import { unstable_cacheTag as cacheTag, unstable_cacheLife as cacheLife } from "next/cache";
import { notFound } from "next/navigation";
import { getServerClient, tags } from "@cimplify/sdk/server";
async function getProduct(slug: string) {
"use cache";
cacheTag(tags.product(slug));
cacheLife("hours");
const r = await getServerClient().catalogue.getProductBySlug(slug);
if (!r.ok) return null;
return r.value;
}
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const product = await getProduct(slug);
if (!product) notFound();
return <pre>{JSON.stringify(product, null, 2)}</pre>;
}Server Actions: revalidate*
After a write, call the matching revalidate* helper to invalidate every cached read tagged with that resource. The helpers wrap Next's revalidateTag so consumers don't have to learn the tag scheme.
"use server";
import { getServerClient, revalidateProducts, revalidateProduct } from "@cimplify/sdk/server";
export async function archiveProduct(productId: string) {
const client = getServerClient();
const r = await client.catalogue.archiveProduct(productId);
if (!r.ok) throw new Error(r.error.message);
await revalidateProduct(productId);
await revalidateProducts();
}Helpers
| Helper | Invalidates |
|---|---|
revalidateProducts() | Products list. |
revalidateProduct(id) | Single product + the products list (denormalized fields are usually embedded). |
revalidateCategories() | Categories list. |
revalidateCategory(id) | Category + its products + the list. |
revalidateCollections() | Collections list. |
revalidateCollection(id) | Collection + its products + the list. |
revalidateBusiness() | Business profile (name, currency, branding). |
revalidateByTag(tag) | Escape hatch; invalidate by raw tag. |
Pre-fetching for client components
SSR-prefetch on the server, hand off as props to a client component. The client component skips its initial fetch and renders instantly.
import { unstable_cacheTag as cacheTag, unstable_cacheLife as cacheLife } from "next/cache";
import { getServerClient, tags } from "@cimplify/sdk/server";
import ShopClient from "./shop-client";
async function getShopData() {
"use cache";
cacheTag(tags.products(), tags.categories());
cacheLife("hours");
const client = getServerClient();
const [products, categories] = await Promise.all([
client.catalogue.getProducts({ limit: 24 }),
client.catalogue.getCategories(),
]);
return {
products: products.ok ? products.value.items : [],
categories: categories.ok ? categories.value : [],
};
}
export default async function Shop() {
const { products, categories } = await getShopData();
return <ShopClient products={products} categories={categories} />;
}"use client";
import { CataloguePage } from "@cimplify/sdk/react";
import type { Product, Category } from "@cimplify/sdk/server";
export default function ShopClient({
products,
categories,
}: {
products: Product[];
categories: Category[];
}) {
return <CataloguePage products={products} categories={categories} pageSize={24} />;
}Env vars
| Variable | Purpose |
|---|---|
CIMPLIFY_SECRET_KEY | Server key for getServerClient. Never expose to the browser. |
CIMPLIFY_API_URL | API base URL (defaults to production; set to http://127.0.0.1:8787 for the local mock). |
NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY | Browser-safe public key for client-side usage. |
Where next
-
React overview Provider, components, hooks.
-
CLI env vars
cimplify env pushfor deployments.
React hooks
30+ hooks from `@cimplify/sdk/react`: typed, cached, and provider-driven. Each requires a `<CimplifyProvider>` ancestor.
Drop-in checkout (hosted Pay)
The fastest path to a paid order: create a checkout session on your server, then redirect the customer to the URL it returns. Cimplify hosts the entire checkout UI at `pay.cimplify.io/s/<sessionId>` (auth, address, payment method, compliance). You get a webhook (or success-URL redirect) when payment lands.