Build
SDKs
One typed core with thin idiomatic bindings. Every binding talks to the same /storefront/v1 contracts and renders region content the same way: constrained block JSON in, safe output — no innerHTML anywhere.
| Package | Type | Description |
|---|---|---|
| @commerceos/sdk | core | Any JS runtime. Typed client + real-DOM region mount. |
| @commerceos/sdk-react | binding | React 18+/Next: provider, hooks, <Region>. |
| @commerceos/sdk-vue | binding | Vue 3.4+: plugin, composables, <Region>. |
| @commerceos/sdk-svelte | binding | Svelte 3/4/5: store contract + use:region action. |
| @commerceos/sdk-astro | binding | Astro/SSG: server client + escaped HTML serializer. |
Core — any runtime
import { createStorefrontClient } from '@commerceos/sdk'; const client = createStorefrontClient({ apiUrl, publishableKey: 'pk_…' });const { items } = await client.products.list({ limit: 12 });const region = await client.regions.get('home-hero'); // vanilla DOM rendering for region block trees:import { mountRegionBlocks } from '@commerceos/sdk';mountRegionBlocks(document.querySelector('#hero')!, region.blocks);
React
import { CommerceProvider, Region, useProducts } from '@commerceos/sdk-react'; <CommerceProvider apiUrl={apiUrl} publishableKey={pk}> <Region name="home-hero" fallback={<p>Loading…</p>} /></CommerceProvider> const { data, loading, error } = useProducts({ limit: 12 });
Vue
import { createCommerce } from '@commerceos/sdk-vue';app.use(createCommerce({ apiUrl, publishableKey: 'pk_…' })); // in a component:const { data } = useProducts();const cart = useCart();
Svelte
<script> import { createCommerce, region } from '@commerceos/sdk-svelte'; const commerce = createCommerce({ apiUrl, publishableKey: 'pk_…' }); const hero = commerce.region('home-hero');</script>{#if $hero.data}<div use:region={$hero.data.blocks} />{/if}<button on:click={() => commerce.cart.addItem(variantId)}> Add · {$commerce.cart.itemCount}</button>
Astro — zero-JS regions
---import { createServerClient, fetchRegion, regionToHtml } from '@commerceos/sdk-astro';const client = createServerClient(import.meta.env);const hero = await fetchRegion(client, 'home-hero');---<section set:html={regionToHtml(hero.blocks)} /># regionToHtml escapes every text node and attribute — zero client JS
Angular
Use the core SDK directly — it is plain TypeScript with zero dependencies. Wrap the client in a service and expose signals or observables however your app prefers:
@Injectable({ providedIn: 'root' })export class CommerceService { readonly client = createStorefrontClient({ apiUrl: env.apiUrl, publishableKey: env.pk, });}
Region rendering is the SDK contract: the block subset (heading, text, image, button, spacer, columns) is documented in Content & regions; every renderer treats stored content as untrusted even though the platform validates at write time.