Next.js quickstart
Wire a Next.js app to the StoreKit Storefront API in about five minutes.
This guide gets a Next.js App Router app reading products, managing a cart, logging customers in, and taking a payment — using the SDK's Next.js adapter.
Prerequisites
- A Next.js app (App Router) on Next 14+ with React 18+.
- A StoreKit store key (publishable API key) and your Storefront API URL. You can create a key from the StoreKit dashboard.
1. Install
npm install @usestorekit/sdk zodzod is a peer dependency used for input validation.
2. Add environment variables
STOREFRONT_API_URL="https://api.your-storekit.com"
STOREFRONT_STORE_KEY="sk_live_xxx"
# Your storefront's public origin — used as the payment return URL.
STOREFRONT_URL="http://localhost:3000"The store key is a server secret. Never expose it to the browser or commit it. The SDK keeps it server-side for you.
3. Create the server instance
initStorekit() reads the env vars above and gives you typed resources for Server Components, Server Actions, and route handlers.
import { initStorekit } from "@usestorekit/sdk/next";
export const storekit = initStorekit();4. Mount the catch-all route handler
This single handler is the bridge the browser talks to. It injects your store key and the customer session on the server, so secrets never reach the client.
import { storekit } from "@/lib/storekit";
export const { GET, POST, PUT, PATCH, DELETE } = storekit.handler();5. Read data in a Server Component
Public catalog reads are automatically cached.
import { storekit } from "@/lib/storekit";
export default async function Home() {
const { data, error } = await storekit.products.list({ limit: 12 });
if (error) return <p>Failed to load products.</p>;
return (
<ul>
{data.data.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}The { data, error } contract
SDK methods never throw by default — they return { data, error }. Check error first, then use data. Learn more in Errors & results.
6. Create the browser client
For interactive UI (add to cart, login), create a browser client. It talks to the same-origin route handler from step 4 — never directly to the API — so your store key stays secret.
"use client";
import { createStorekitClient } from "@usestorekit/sdk/react";
export const storefront = createStorekitClient();Now use the hooks anywhere in a Client Component:
"use client";
import { storefront } from "@/lib/storekit-client";
export function AddToCart({ variantId }: { variantId: string }) {
const { add, count } = storefront.useCart();
return (
<button onClick={() => add({ variantId, quantity: 1 })}>
Add to cart ({count})
</button>
);
}7. Take a payment
Create a checkout on the server, redirect to the payment provider, and reconcile when the customer returns.
"use server";
import { redirect } from "next/navigation";
import { storekit } from "@/lib/storekit";
export async function checkout() {
const { data, error } = await storekit.checkout.create({
orderType: "delivery",
shipping: {
firstName: "Ada",
address: "1 Market St",
city: "Bengaluru",
state: "KA",
zipCode: "560001",
country: "IN",
},
});
if (error) throw error;
redirect(data.redirectUrl); // hand off to the payment provider
}Add the return page the provider redirects back to:
"use client";
import { useSearchParams } from "next/navigation";
import { storefront } from "@/lib/storekit-client";
export default function PaymentCallback() {
const orderId = useSearchParams().get("orderId");
const { status, message } = storefront.usePaymentConfirmation(orderId);
if (status === "processing") return <p>Confirming your payment…</p>;
if (status === "success") return <p>Thank you! Your order is confirmed.</p>;
return <p>{message ?? "We couldn't confirm your payment."}</p>;
}That's it — you have catalog, cart, auth, and payments wired up. Read Payments for the full redirect flow.