Next.js integration
Use @easylabs/node in a Next.js project — guided tour of the example app.
A complete, runnable Next.js example lives at easy-sdk/examples/next-example. This page is a guided tour — it points to the most-relevant files in that example so you can see the SDK wired into a real project, not just isolated snippets.
Source code
- Repository:
itseasyco/easy-sdk - Path:
examples/next-example
What this example covers
- Customer signup with a synced local user record (Prisma) and an Easy customer.
- Admin dashboards backed by Server Components + Server Actions hitting the SDK.
- Product / price catalog management (create, edit, archive — both products and prices).
- Subscription lifecycle (list, create, cancel).
- Order detail pages with refund / fulfilment actions.
- Disputes triage screen.
- Revenue + analytics widgets.
- Profile screen with stored payment instruments.
Key files
| File | Demonstrates |
|---|---|
src/lib/easy-sync.ts | Lazy singleton (getEasyClient) wrapping createClient so a single SDK instance is reused across server-side modules. |
src/app/api/auth/signup/route.ts | Route Handler that creates a local user + an Easy customer in one step. |
src/app/admin/products/actions.ts | Server Actions calling createProduct, updateProduct, archiveProduct. |
src/app/admin/subscriptions/actions.ts | createSubscription, cancelSubscription from a Server Action invoked by a Client Component. |
src/app/admin/orders/[id]/actions.ts | Order detail mutations (updateOrderTags, refund flows). |
src/app/admin/disputes/actions.ts | Dispute triage (acceptDispute, updateDispute, evidence upload). |
src/app/checkout/page.tsx | Buyer-side checkout wiring (delegates to @easylabs/react for the UI). |
The lazy-singleton pattern is what most teams copy first:
// src/lib/easy-sync.ts
import { createClient } from "@easylabs/node";
let easyClient: Awaited<ReturnType<typeof createClient>> | null = null;
async function getEasyClient() {
if (easyClient) return easyClient;
if (!process.env.EASY_API_KEY) throw new Error("EASY_API_KEY is required");
easyClient = await createClient({ apiKey: process.env.EASY_API_KEY });
return easyClient;
}Call getEasyClient() from any Server Component, Server Action, or Route Handler. Never import this module from a Client Component — the SDK is server-only.
Run it locally
git clone https://github.com/itseasyco/easy-sdk.git
cd easy-sdk
pnpm install
pnpm --filter next-example db:init # provisions the local Prisma DB
cd examples/next-example
echo "EASY_API_KEY=sk_test_..." > .env.local
pnpm dev
# http://localhost:3000Adapting it
- Cache the SDK at module scope. Next.js may hot-reload modules in dev — the
let easyClientcache survives normal renders but resets on reload. That's fine; the validation cost is low. In production it's effectively a process singleton. - Pin the runtime. Set
export const runtime = "nodejs"on Route Handlers and Server Actions that use the SDK —@easylabs/nodedepends onnode:crypto/FormDataand won't run on the Edge runtime. - Webhooks. The example doesn't include a webhook route. Add one as a Route Handler with
await req.text()to capture the raw body, thenEasyWebhooks.constructEvent(rawBody, sig, secret). See Webhooks. - Tenant scoping. Replace the singleton with a
Map<tenantId, Promise<EasyClient>>cache keyed on the merchant ID resolved from the session. - Strip the
NEXT_PUBLIC_prefix. The example readsNEXT_PUBLIC_EASY_API_KEYfor local dev convenience — do not deploy with a public-prefixed secret. Read from a non-public env var on the server.