@commercengine/storefront
v0.1.7
Published
Framework wrappers for the Commerce Engine Storefront SDK
Maintainers
Readme
@commercengine/storefront
Framework-facing package for Commerce Engine storefront applications.
Use this package when you are building an app:
- SPA / vanilla React + Vite: import from
@commercengine/storefront - Astro: import wrapper helpers from
@commercengine/storefront/astro - Next.js: import wrapper helpers from
@commercengine/storefront/nextjs - SvelteKit: import wrapper helpers from
@commercengine/storefront/sveltekit - TanStack Start: import wrapper helpers from
@commercengine/storefront/tanstack-start
Use @commercengine/storefront-sdk directly only when you want the standalone
isomorphic core SDK, and use @commercengine/ssr-utils directly only when you
are building a custom framework binding that Commerce Engine does not ship.
Installation
pnpm add @commercengine/storefrontSPA / Core Usage
The root entry is a direct pass-through of @commercengine/storefront-sdk.
import { Environment, createStorefront } from "@commercengine/storefront";
const storefront = createStorefront({
storeId: "your-store-id",
apiKey: "your-api-key",
environment: Environment.Staging,
});
const publicSdk = storefront.public();
const sessionSdk = storefront.session();For browser script-tag usage, the root package also ships an IIFE bundle at
@commercengine/storefront/iife, exposing the same window.CE_SDK global as
the standalone core package.
Next.js
import { Environment } from "@commercengine/storefront";
import { createNextjsStorefront } from "@commercengine/storefront/nextjs";
export const storefront = createNextjsStorefront({
storeId: process.env.NEXT_PUBLIC_STORE_ID!,
apiKey: process.env.NEXT_PUBLIC_API_KEY!,
environment: Environment.Staging,
});Usage:
const publicSdk = storefront.publicStorefront();
const clientSdk = storefront.clientStorefront();
const serverSdk = await storefront.serverStorefront();Recommended bootstrap pattern:
// lib/storefront-bootstrap.client.tsx
"use client";
import { useEffect } from "react";
import { storefront } from "./storefront";
export function StorefrontBootstrap() {
useEffect(() => {
storefront.bootstrap().catch(console.error);
}, []);
return null;
}Mount this once near the root of your app. This is the recommended framework
pattern because it establishes the anonymous session in a place where cookies
can be written reliably before later server-side serverStorefront() reads
depend on it.
Cold server-component reads are not an equivalent substitute. If the first session-bound call happens in a Server Component with no existing cookies, the SDK may create an anonymous token for that request but cannot rely on persisting it there, so session continuity is not guaranteed.
Astro
Define the shared config once:
// src/lib/storefront-config.ts
import { Environment } from "@commercengine/storefront";
import type { AstroStorefrontConfig } from "@commercengine/storefront/astro";
export const storefrontConfig: AstroStorefrontConfig = {
storeId: import.meta.env.PUBLIC_STORE_ID!,
apiKey: import.meta.env.PUBLIC_API_KEY!,
environment: Environment.Staging,
};Client-side usage:
// src/lib/storefront.ts
import { createAstroStorefront } from "@commercengine/storefront/astro";
import { storefrontConfig } from "./storefront-config";
export const storefront = createAstroStorefront(storefrontConfig);const publicSdk = storefront.publicStorefront();
const clientSdk = storefront.clientStorefront();Recommended bootstrap pattern:
// src/lib/storefront-client.ts
import { storefront } from "./storefront";
let bootstrapPromise: Promise<void> | null = null;
export function bootstrapStorefront() {
if (bootstrapPromise) return bootstrapPromise;
bootstrapPromise = storefront.bootstrap().catch((error) => {
bootstrapPromise = null;
throw error;
});
return bootstrapPromise;
}---
---
<script type="module">
import { bootstrapStorefront } from "../lib/storefront-client";
const run = () => void bootstrapStorefront();
document.addEventListener("astro:page-load", run);
run();
</script>Server-only usage:
// src/lib/server-storefront.ts
import { createAstroServerStorefront } from "@commercengine/storefront/astro/server";
import { storefrontConfig } from "./storefront-config";
export const serverStorefront = createAstroServerStorefront(storefrontConfig);const sessionSdk = serverStorefront.serverStorefront(Astro.cookies);SvelteKit
Define the shared config once:
// src/lib/storefront-config.ts
import { Environment } from "@commercengine/storefront";
import type { SvelteKitStorefrontConfig } from "@commercengine/storefront/sveltekit";
import { env } from "$env/static/public";
export const storefrontConfig: SvelteKitStorefrontConfig = {
storeId: env.PUBLIC_STORE_ID,
apiKey: env.PUBLIC_API_KEY,
environment: Environment.Staging,
};Client-side usage:
// src/lib/storefront.ts
import { createSvelteKitStorefront } from "@commercengine/storefront/sveltekit";
import { storefrontConfig } from "./storefront-config";
export const storefront = createSvelteKitStorefront(storefrontConfig);const publicSdk = storefront.publicStorefront();
const clientSdk = storefront.clientStorefront();Recommended bootstrap pattern:
<!-- src/routes/+layout.svelte -->
<script>
import { onMount } from "svelte";
import { storefront } from "$lib/storefront";
onMount(() => {
storefront.bootstrap().catch(console.error);
});
</script>
<slot />Mount this once in your root layout. This establishes the anonymous session
on the client before later server-side serverStorefront() reads depend on
cookie continuity.
Server-only usage:
// src/lib/server/storefront.ts
import { createSvelteKitServerStorefront } from "@commercengine/storefront/sveltekit/server";
import { storefrontConfig } from "$lib/storefront-config";
export const serverStorefront =
createSvelteKitServerStorefront(storefrontConfig);// src/routes/+page.server.ts
import { serverStorefront } from "$lib/server/storefront";
export async function load({ cookies }) {
const sessionSdk = serverStorefront.serverStorefront(cookies);
const cart = await sessionSdk.cart.getCart();
return { cart: cart.data };
}TanStack Start
Define the shared config once:
// app/lib/storefront-config.ts
import { Environment } from "@commercengine/storefront";
import type { TanStackStartStorefrontConfig } from "@commercengine/storefront/tanstack-start";
export const storefrontConfig: TanStackStartStorefrontConfig = {
storeId: import.meta.env.VITE_STORE_ID,
apiKey: import.meta.env.VITE_API_KEY,
environment: Environment.Staging,
};Client-side usage:
// app/lib/storefront.ts
import { createTanStackStartStorefront } from "@commercengine/storefront/tanstack-start";
import { storefrontConfig } from "./storefront-config";
export const storefront = createTanStackStartStorefront(storefrontConfig);const publicSdk = storefront.publicStorefront();
const clientSdk = storefront.clientStorefront();Server-only usage:
// app/lib/server-storefront.ts
import { createTanStackStartServerStorefront } from "@commercengine/storefront/tanstack-start/server";
import { storefrontConfig } from "./storefront-config";
export const serverStorefront =
createTanStackStartServerStorefront(storefrontConfig);
const sessionSdk = serverStorefront.serverStorefront();Recommended bootstrap pattern follows the same shape: create a small
client-only component and call storefront.bootstrap() in a mount effect.
This should be the default documented approach whenever your app expects later
server-side session reads to see an already-established anonymous session.
