Skip to main content

๐Ÿง  Shopify Client SDK

Welcome to the heart of @nextshopkit/sdk and @nextshopkit/pro.
Everything starts with createShopifyClient() โ€” a typed, server-safe way to access Shopifyโ€™s Storefront API.


๐Ÿ›  What is the client?โ€‹

The client is your gateway to Shopify. It wraps all of your requests and gives you access to prebuilt methods like:

  • getProduct() โ€” Fetch a single product by handle
  • getCollection() โ€” Fetch multiple products with filters, sorting, and pagination within a collection
  • getPolicies() โ€” Fetch refund, privacy, terms, and shipping policies (PRO only)

โš™๏ธ Initializing the clientโ€‹

You only need to do this once โ€” usually inside:

lib/NextShopKit/client.ts
Caching & Performance Notes

When initializing the client, you can optionally enable caching to improve performance:

  • enableMemoryCache: stores Shopify responses in memory for quicker reuse
  • enableVercelCache: integrates with Vercel ISR caching (use with revalidate)
  • defaultCacheTtl: memory cache duration in seconds
  • defaultRevalidate: Vercel revalidate time in seconds

These options reduce redundant API calls and improve response times.

import {
createShopifyClient,
GetProductOptions,
FetchProductResult,
GetPoliciesOptions,
FetchPoliciesResult,
GetCollectionOptions,
FetchCollectionResult,
} from "@nextshopkit/sdk"; // or "@nextshopkit/pro"

// Cache options can be used both for CORE and PRO tier.
const client = createShopifyClient({
shop: process.env.SHOPIFY_STORE_DOMAIN!,
token: process.env.SHOPIFY_ACCESS_TOKEN!,
apiVersion: "2025-01",
enableMemoryCache: true,
defaultCacheTtl: 300,
enableVercelCache: true,
defaultRevalidate: 60,
});

// The cache option specified here overrides the default
// client-level cache settings and is exclusively available
// in the PRO tier. Note that the CORE tier does not
// support function-specific cache configurations.
export const getProduct = async (
args: GetProductOptions
): Promise<FetchProductResult> =>
client.getProduct(args, {
cacheTtl: 60,
revalidate: 60,
useMemoryCache: true,
useVercelCache: true,
});

export const getCollection = async (
args: GetCollectionOptions
): Promise<FetchCollectionResult> => client.getCollection(args);

export const getPolicies = async (
args: GetPoliciesOptions
): Promise<FetchPoliciesResult> => client.getPolicies(args);

export default client;

๐Ÿ” Environment Variablesโ€‹

Your .env.local file must contain:

SHOPIFY_ACCESS_TOKEN=your-access-token
SHOPIFY_STORE_DOMAIN=your-store.myshopify.com

These values are never exposed to the client. Always use the SDK on the server only.


๐Ÿงฉ What does the client return?โ€‹

Every SDK method returns the same structure:

const { data, error } = await getProduct({ handle: "solar-kit-9kw" });

if (error || !data) {
// Handle the error gracefully
}

You always get:

  • data: the structured result (or null if not found)
  • error: a parsed error object (or null if success)

๐Ÿ“š Method Overviewโ€‹

MethodDescriptionTierLink
getProduct()Fetch a product by handleCORE/PROSee docs โ†’
getCollection()Fetch multiple products with filters & sortingCORE/PROSee docs โ†’
getPolicies()Fetch shop policies (refund, privacy, etc.)PROSee docs โ†’

โš ๏ธ Server-only usage requiredโ€‹

Never use this SDK in client components!

Because it uses secrets from .env, you must use these functions only:

  • Inside server components (App Router)
  • In "use server" utilities
  • In API routes or route handlers

Using it on the client would expose sensitive data.


โœ… Best practicesโ€‹

  • Place the client setup inside lib/NextShopKit/client.ts
  • Create wrappers like getProduct, getCollection, and getPolicies so you can mock or extend them later
  • Handle error and null data gracefully
  • Group usage per domain (lib/NextShopKit/products.ts, cart.ts, etc.)

๐Ÿงช Need examples?โ€‹