npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@commercengine/ssr-utils

v0.1.0

Published

Framework-agnostic SSR utilities for Commerce Engine SDKs

Readme

@commercengine/ssr-utils

Framework-agnostic SSR utilities for Commerce Engine SDKs. Provides shared token storage and cookie handling that works across all major meta-frameworks.

Note: This is a low-level utility package. For Next.js projects, use @commercengine/storefront-sdk-nextjs which builds on this package and provides a complete solution with request isolation, universal API, automatic context detection, and React integration.

Features

  • Universal Cookie Adapter - Abstract interface that works with any framework's cookie API
  • Server Token Storage - Request-scoped token storage for SSR contexts
  • Build-Time Caching - Intelligent token caching for SSG/ISR builds
  • Environment Detection - Utilities to detect server, client, and build contexts
  • Zero Dependencies - Lightweight, no framework-specific dependencies

Installation

npm install @commercengine/ssr-utils
# or
pnpm add @commercengine/ssr-utils

Quick Start

For Next.js users: Skip this section and use @commercengine/storefront-sdk-nextjs instead. It handles request isolation, client/server detection, build optimization, and provides a much simpler API.

The examples below show how to use ssr-utils directly for building framework-specific integrations (like we did for Next.js) or for frameworks without an official SDK wrapper.

Basic Usage (Any Framework)

import { ServerTokenStorage } from '@commercengine/ssr-utils';
import { StorefrontSDK } from '@commercengine/storefront-sdk';

// Create adapter for your framework's cookie API
const tokenStorage = new ServerTokenStorage({
  get: (name) => /* get cookie by name */,
  set: (name, value, opts) => /* set cookie */,
  delete: (name) => /* delete cookie */,
});

const sdk = new StorefrontSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  tokenStorage,
});

SvelteKit

// src/routes/+page.server.ts
import { ServerTokenStorage } from '@commercengine/ssr-utils';
import { StorefrontSDK } from '@commercengine/storefront-sdk';
import { env } from '$env/dynamic/private';

export async function load({ cookies }) {
  const tokenStorage = new ServerTokenStorage({
    get: (name) => cookies.get(name) ?? null,
    set: (name, value, opts) => cookies.set(name, value, opts),
    delete: (name) => cookies.delete(name),
  });

  const sdk = new StorefrontSDK({
    storeId: env.STORE_ID,
    apiKey: env.API_KEY,
    tokenStorage,
  });

  const { data } = await sdk.catalog.listProducts();
  return { products: data?.products ?? [] };
}

Nuxt (h3)

// server/api/products.ts
import { getCookie, setCookie, deleteCookie, defineEventHandler } from 'h3';
import { ServerTokenStorage } from '@commercengine/ssr-utils';
import { StorefrontSDK } from '@commercengine/storefront-sdk';

export default defineEventHandler(async (event) => {
  const tokenStorage = new ServerTokenStorage({
    get: (name) => getCookie(event, name) ?? null,
    set: (name, value, opts) => setCookie(event, name, value, opts),
    delete: (name) => deleteCookie(event, name),
  });

  const sdk = new StorefrontSDK({
    storeId: process.env.STORE_ID!,
    apiKey: process.env.API_KEY!,
    tokenStorage,
  });

  const { data } = await sdk.catalog.listProducts();
  return { products: data?.products ?? [] };
});

Astro

// src/pages/products.astro
---
import { ServerTokenStorage } from '@commercengine/ssr-utils';
import { StorefrontSDK } from '@commercengine/storefront-sdk';

const tokenStorage = new ServerTokenStorage({
  get: (name) => Astro.cookies.get(name)?.value ?? null,
  set: (name, value, opts) => Astro.cookies.set(name, value, opts),
  delete: (name) => Astro.cookies.delete(name),
});

const sdk = new StorefrontSDK({
  storeId: import.meta.env.STORE_ID,
  apiKey: import.meta.env.API_KEY,
  tokenStorage,
});

const { data } = await sdk.catalog.listProducts();
const products = data?.products ?? [];
---

<ul>
  {products.map(product => <li>{product.name}</li>)}
</ul>

API Reference

ServerTokenStorage

Cookie-based token storage for server-side rendering contexts.

import { ServerTokenStorage, type CookieAdapter } from '@commercengine/ssr-utils';

const adapter: CookieAdapter = {
  get: (name) => /* get cookie value */,
  set: (name, value, options) => /* set cookie */,
  delete: (name) => /* delete cookie */,
};

const storage = new ServerTokenStorage(adapter, {
  prefix: 'ce_',           // Cookie name prefix (default: 'ce_')
  maxAge: 2592000,         // Cookie max age in seconds (default: 30 days)
  path: '/',               // Cookie path (default: '/')
  domain: undefined,       // Cookie domain (default: current domain)
  secure: true,            // HTTPS only (default: auto-detect)
  sameSite: 'lax',         // SameSite attribute (default: 'lax')
});

BuildCachingTokenStorage

In-memory token storage with caching for SSG/ISR build contexts. Tokens are cached and reused across pages during static generation.

import { BuildCachingTokenStorage } from '@commercengine/ssr-utils';

const storage = new BuildCachingTokenStorage({
  cacheKey: 'my-store:production',  // Unique key for caching
  ttlSeconds: 300,                   // Cache TTL (default: 5 minutes)
});

Environment Detection

Utilities to detect the current execution context.

import { isServer, isClient, isBuildContext } from '@commercengine/ssr-utils';

// Check if running on server
if (isServer()) {
  // Server-side code
}

// Check if running in browser
if (isClient()) {
  // Client-side code
}

// Check if running during static build
if (isBuildContext()) {
  // Build-time code (SSG/ISR)
}

// Custom build detection
if (isBuildContext({
  envVars: ['NEXT_IS_BUILD', 'NUXT_BUILD', 'CI']
})) {
  // Custom environment variable detection
}

createTokenStorage

Factory function to create the appropriate token storage based on context.

import { createTokenStorage } from '@commercengine/ssr-utils';

const tokenStorage = createTokenStorage({
  cookieAdapter: adapter,      // Optional: cookie adapter for server contexts
  buildCacheKey: 'my-store',   // Optional: enables build-time caching
  options: {                   // Optional: storage options
    prefix: 'ce_',
    maxAge: 2592000,
  },
});

Types

CookieAdapter

Framework-agnostic interface for cookie operations.

interface CookieAdapter {
  get(name: string): string | null;
  set(name: string, value: string, options?: CookieOptions): void;
  delete(name: string): void;
}

CookieOptions

Standard cookie options that work across frameworks.

interface CookieOptions {
  maxAge?: number;                         // Seconds until expiry
  path?: string;                           // Cookie path
  domain?: string;                         // Cookie domain
  secure?: boolean;                        // HTTPS only
  sameSite?: 'strict' | 'lax' | 'none';   // SameSite attribute
  httpOnly?: boolean;                      // HTTP only (no JS access)
}

SSRTokenStorageOptions

Configuration for token storage instances.

interface SSRTokenStorageOptions {
  prefix?: string;                         // Cookie name prefix
  maxAge?: number;                         // Cookie max age
  path?: string;                           // Cookie path
  domain?: string;                         // Cookie domain
  secure?: boolean;                        // HTTPS only
  sameSite?: 'strict' | 'lax' | 'none';   // SameSite attribute
}

TokenStorage

Interface that all token storage implementations follow.

interface TokenStorage {
  getAccessToken(): Promise<string | null>;
  setAccessToken(token: string): Promise<void>;
  getRefreshToken(): Promise<string | null>;
  setRefreshToken(token: string): Promise<void>;
  clearTokens(): Promise<void>;
}

Build Cache API

Low-level API for direct cache manipulation (advanced use cases).

import {
  getCachedToken,
  setCachedToken,
  clearCachedToken,
  clearAllCachedTokens,
  getCacheStats,
} from '@commercengine/ssr-utils';

// Get cached token
const token = getCachedToken('my-store', 'access');

// Set cached token with TTL
setCachedToken('my-store', 'access', 'token-value', 300);

// Clear specific token
clearCachedToken('my-store', 'access');

// Clear all cached tokens
clearAllCachedTokens();

// Get cache statistics
const stats = getCacheStats();
// { size: 2, keys: ['my-store:access', 'my-store:refresh'] }

Why ssr-utils?

The Problem

Every SSR framework has its own cookie API:

  • Next.js: cookies() from next/headers
  • SvelteKit: cookies parameter in load functions
  • Nuxt/h3: getCookie(), setCookie() from h3
  • Astro: Astro.cookies

Building a production-ready SDK integration for each framework requires solving:

  • Cookie-based token storage
  • Build-time token caching for SSG/ISR
  • Environment detection (server/client/build)

The Solution

ssr-utils extracts the common building blocks so framework-specific SDKs can focus on framework-specific concerns:

| Layer | Responsibility | |-------|----------------| | ssr-utils | Cookie abstraction, token storage, build caching | | Framework SDK (e.g., nextjs) | Request isolation, context detection, DX patterns, React integration |

This package is for:

  • Building new framework-specific SDK wrappers (SvelteKit, Nuxt, Astro, etc.)
  • Advanced users who need low-level control
  • Frameworks without an official SDK wrapper

Use the framework SDK instead if available:

  • Next.js → @commercengine/storefront-sdk-nextjs

Related Packages

License

All Rights Reserved