@spree/docs 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -183,7 +183,6 @@ pnpm dev
183
183
  | Package | Path | Description |
184
184
  |---|---|---|
185
185
  | `@spree/sdk` | `packages/sdk` | TypeScript SDK for the Spree Storefront API |
186
- | `@spree/next` | `packages/next` | Next.js integration (server actions, caching, cookie-based auth) |
187
186
 
188
187
  ### Common commands
189
188
 
@@ -317,7 +316,7 @@ To help us review your PR quickly:
317
316
  - **Describe your changes.** Explain what you changed and why. Include screenshots for UI changes.
318
317
  - **Add tests.** All new features and bug fixes should include appropriate test coverage.
319
318
  - **Update documentation.** If your change affects user-facing behavior, update the relevant docs.
320
- - **Include a changeset** (TypeScript packages only). Run `pnpm changeset` if your change affects `@spree/sdk` or `@spree/next`.
319
+ - **Include a changeset** (TypeScript packages only). Run `pnpm changeset` if your change affects `@spree/sdk`.
321
320
  - **Ensure CI passes.** PRs with failing CI will not be reviewed.
322
321
 
323
322
  ## Reporting Bugs
@@ -164,7 +164,6 @@ Spree is distributed as a set of packages:
164
164
  | Package | Purpose |
165
165
  |---------|---------|
166
166
  | [`@spree/sdk`](../sdk/quickstart.md) | TypeScript SDK for Store API and Admin API |
167
- | [`@spree/next`](../storefront/nextjs/spree-next-package.md) | Next.js integration — server actions, caching, cookie-based auth |
168
167
 
169
168
  > **INFO:** For headless commerce, you only need the `spree` package. Build your customer-facing frontend with any technology (Next.js, Nuxt, mobile apps) using the Store API and SDK.
170
169
 
@@ -165,27 +165,9 @@ Each webhook request includes these headers:
165
165
 
166
166
  To ensure webhooks are genuinely from your Spree store, verify the signature.
167
167
 
168
- #### Next.js (recommended)
168
+ #### Next.js
169
169
 
170
- Use `@spree/next/webhooks` for a ready-made Route Handler:
171
-
172
- ```typescript
173
- // src/app/api/webhooks/spree/route.ts
174
- import { createWebhookHandler } from '@spree/next/webhooks'
175
-
176
- export const POST = createWebhookHandler({
177
- secret: process.env.SPREE_WEBHOOK_SECRET!,
178
- handlers: {
179
- 'order.completed': async (event) => {
180
- // event.data is the order payload (same shape as Store API)
181
- await sendOrderConfirmationEmail(event.data)
182
- },
183
- 'order.canceled': async (event) => {
184
- await sendCancellationEmail(event.data)
185
- },
186
- },
187
- })
188
- ```
170
+ The [Spree Storefront](https://github.com/spree/storefront) includes a ready-made webhook route handler with signature verification and event routing. See the [storefront email docs](../storefront/nextjs/customization.md#transactional-emails) for details.
189
171
 
190
172
  #### Any JavaScript/TypeScript framework
191
173
 
@@ -36,8 +36,6 @@ const cart = await client.carts.create({
36
36
  metadata: { source: 'mobile_app', campaign: 'summer_sale' }
37
37
  })
38
38
 
39
- // @spree/next
40
- const cart = await getOrCreateCart({ source: 'mobile_app' })
41
39
  ```
42
40
 
43
41
  ### Adding items
@@ -35,7 +35,7 @@ RESEND_API_KEY=re_your_resend_api_key
35
35
  EMAIL_FROM=Your Store <orders@your-domain.com>
36
36
  ```
37
37
 
38
- 3. **The storefront handles everything else** — signature verification, event routing, email rendering, and delivery are built into `@spree/next/webhooks`. See the [Next.js storefront email docs](../storefront/nextjs/customization.md#transactional-emails) for template customization.
38
+ 3. **The storefront handles everything else** — signature verification, event routing, email rendering, and delivery are built in. See the [Next.js storefront email docs](../storefront/nextjs/customization.md#transactional-emails) for template customization.
39
39
 
40
40
  ### Supported Events
41
41
 
@@ -9,10 +9,10 @@ The storefront follows a **server-first architecture** where all API calls are m
9
9
 
10
10
  ```
11
11
  Browser → Server Action → @spree/sdk → Spree API
12
- (with httpOnly cookies via @spree/next helpers)
12
+ (with httpOnly cookies via src/lib/spree helpers)
13
13
  ```
14
14
 
15
- - **Server Actions** (`src/lib/data/`) — call `@spree/sdk` directly with auth/cookie helpers from `@spree/next`
15
+ - **Server Actions** (`src/lib/data/`) — call `@spree/sdk` directly with auth/cookie helpers from `src/lib/spree`
16
16
  - **httpOnly Cookies** — auth tokens, cart tokens, and locale are stored securely
17
17
  - **No Client-Side API Calls** — the Spree API key stays on the server
18
18
  - **Auto-Localization** — locale and country are read from cookies via `getLocaleOptions()`
@@ -85,13 +85,13 @@ src/
85
85
 
86
86
  1. User submits login form
87
87
  2. Server action calls `@spree/sdk` to authenticate
88
- 3. JWT token is stored in an httpOnly cookie via `@spree/next` cookie helpers
88
+ 3. JWT token is stored in an httpOnly cookie via `src/lib/spree` cookie helpers
89
89
  4. Subsequent requests use `withAuthRefresh()` which reads the token from cookies automatically
90
90
  5. Token is never accessible to client-side JavaScript
91
91
 
92
92
  ```typescript
93
93
  // src/lib/data/customer.ts
94
- import { getClient, withAuthRefresh, setAccessToken, setRefreshToken } from '@spree/next'
94
+ import { getClient, withAuthRefresh, setAccessToken, setRefreshToken } from '@/lib/spree'
95
95
 
96
96
  export async function login(email: string, password: string) {
97
97
  const result = await getClient().auth.login({ email, password })
@@ -117,11 +117,11 @@ The storefront supports multiple countries and currencies via URL segments:
117
117
  /uk/en/products # UK store, English
118
118
  ```
119
119
 
120
- A middleware (`src/proxy.ts`) uses `createSpreeMiddleware` from `@spree/next` to detect the visitor's country and locale, then redirects to the correct URL prefix. The `CountrySwitcher` component lets users change regions manually.
120
+ A middleware (`src/proxy.ts`) uses `createSpreeMiddleware` from `src/lib/spree` to detect the visitor's country and locale, then redirects to the correct URL prefix. The `CountrySwitcher` component lets users change regions manually.
121
121
 
122
122
  ## Server Actions
123
123
 
124
- All data fetching is done through server actions in `src/lib/data/`. These call `@spree/sdk` directly, using `@spree/next` helpers for auth and locale:
124
+ All data fetching is done through server actions in `src/lib/data/`. These call `@spree/sdk` directly, using `src/lib/spree` helpers for auth and locale:
125
125
 
126
126
  ```typescript
127
127
  // Products — use getLocaleOptions() for locale-aware reads
@@ -111,7 +111,7 @@ To customize API behavior, modify the server actions in `src/lib/data/`. Each fi
111
111
  | `gift-cards.ts` | Gift card management |
112
112
  | `utils.ts` | Shared helpers (error handling, fallbacks) |
113
113
 
114
- These server actions call `@spree/sdk` directly, using `@spree/next` helpers for auth cookies and locale resolution. You can add custom logic, caching strategies, or additional transformations as needed.
114
+ These server actions call `@spree/sdk` directly, using helpers in `src/lib/spree/` for auth cookies and locale resolution. You can add custom logic, caching strategies, or additional transformations as needed.
115
115
 
116
116
  ## Adding New Pages
117
117
 
@@ -163,10 +163,10 @@ Opens the react-email dev server with mock data for all templates at `http://loc
163
163
 
164
164
  ### Webhook Handler
165
165
 
166
- The webhook route (`src/app/api/webhooks/spree/route.ts`) uses `createWebhookHandler` from `@spree/next/webhooks`:
166
+ The webhook route (`src/app/api/webhooks/spree/route.ts`) uses `createWebhookHandler` from `src/lib/spree/webhooks`:
167
167
 
168
168
  ```typescript
169
- import { createWebhookHandler } from '@spree/next/webhooks'
169
+ import { createWebhookHandler } from '@/lib/spree/webhooks'
170
170
 
171
171
  export const POST = createWebhookHandler({
172
172
  secret: process.env.SPREE_WEBHOOK_SECRET!,
@@ -198,4 +198,4 @@ For full setup details, see [Sending out Emails](../../deployment/emails.md).
198
198
 
199
199
  ## Building a Custom Storefront
200
200
 
201
- If you prefer to build from scratch instead of forking the starter, you can use the `@spree/next` and `@spree/sdk` packages directly in any Next.js application. See the [@spree/next Package](spree-next-package.md) documentation for the complete API reference.
201
+ If you prefer to build from scratch instead of forking the starter, you can use the `@spree/sdk` package directly in any Next.js application. The storefront's `src/lib/spree/` directory contains reusable helpers for cookie-based auth, locale resolution, middleware, and webhook verification that you can copy into your own project.
@@ -12,7 +12,6 @@ The [Spree Storefront](https://github.com/spree/storefront) is a production-read
12
12
  - **Tailwind CSS 4** - Utility-first styling
13
13
  - **TypeScript 5** - Full type safety
14
14
  - **[@spree/sdk](https://github.com/spree/spree/tree/main/packages/sdk)** - Official Spree Commerce SDK
15
- - **[@spree/next](https://github.com/spree/spree/tree/main/packages/next)** - Cookie-based auth, middleware, and webhook helpers
16
15
  - **Sentry** - Error tracking and performance monitoring
17
16
 
18
17
  ## Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spree/docs",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Spree Commerce developer documentation for AI agents and local reference",
5
5
  "type": "module",
6
6
  "license": "CC-BY-4.0",
@@ -1,247 +0,0 @@
1
- ---
2
- title: "@spree/next Package"
3
- description: Next.js integration library — cookie-based auth, middleware, and webhook helpers
4
- ---
5
-
6
- The `@spree/next` package provides the server-side plumbing for building a Next.js storefront with `@spree/sdk`: JWT token lifecycle, httpOnly cookie management, locale/country middleware, and webhook verification.
7
-
8
- Your storefront calls `@spree/sdk` directly for all API operations. `@spree/next` handles the Next.js-specific concerns — cookies, auth refresh, and middleware — so you don't have to.
9
-
10
- ## Installation
11
-
12
- ```bash
13
- npm install @spree/next @spree/sdk
14
- ```
15
-
16
- ## Configuration
17
-
18
- ### Auto-initialization
19
-
20
- Set environment variables and the client initializes automatically:
21
-
22
- ```env
23
- SPREE_API_URL=https://api.mystore.com
24
- SPREE_PUBLISHABLE_KEY=spree_pk_xxx
25
-
26
- # Required for webhook-based emails (see Webhooks section below)
27
- SPREE_WEBHOOK_SECRET=your_webhook_endpoint_secret_key
28
- ```
29
-
30
- ### Explicit initialization
31
-
32
- ```typescript
33
- // lib/storefront.ts
34
- import { initSpreeNext } from '@spree/next';
35
-
36
- initSpreeNext({
37
- baseUrl: process.env.SPREE_API_URL!,
38
- publishableKey: process.env.SPREE_PUBLISHABLE_KEY!,
39
- cartCookieName: '_spree_cart_token', // default
40
- accessTokenCookieName: '_spree_jwt', // default
41
- defaultLocale: 'en',
42
- defaultCurrency: 'USD',
43
- defaultCountry: 'US',
44
- });
45
- ```
46
-
47
- ## Architecture
48
-
49
- `@spree/next` provides four things:
50
-
51
- 1. **`getClient()`** — singleton `@spree/sdk` Client instance (auto-inits from env vars)
52
- 2. **Auth helpers** — `withAuthRefresh()` for JWT lifecycle, cookie read/write for tokens
53
- 3. **Locale resolution** — `getLocaleOptions()` reads country/locale from cookies
54
- 4. **Framework helpers** — `createSpreeMiddleware()` for URL routing, `createWebhookHandler()` for webhooks
55
-
56
- Your storefront's server actions call `@spree/sdk` directly, using these helpers for auth and cookies:
57
-
58
- ```
59
- Server Action → getClient().products.list(params, localeOptions)
60
- Server Action → withAuthRefresh(fn) → getClient().customer.get(options)
61
- Server Action → getCartOptions() → getClient().carts.items.create(...)
62
- ```
63
-
64
- ## Auth Helpers
65
-
66
- ### `withAuthRefresh(fn)`
67
-
68
- Wraps an authenticated SDK call with automatic token management:
69
-
70
- 1. Reads JWT from cookie
71
- 2. Proactively refreshes if expiring within 5 minutes
72
- 3. Executes your function with `{ token }` options
73
- 4. On 401: refreshes token and retries once
74
- 5. On refresh failure: clears cookies and throws
75
-
76
- ```typescript
77
- 'use server';
78
-
79
- import { getClient, withAuthRefresh } from '@spree/next';
80
-
81
- export async function getCustomer() {
82
- return withAuthRefresh(async (options) => {
83
- return getClient().customer.get(options);
84
- });
85
- }
86
-
87
- export async function listAddresses() {
88
- return withAuthRefresh(async (options) => {
89
- return getClient().customer.addresses.list(undefined, options);
90
- });
91
- }
92
- ```
93
-
94
- ### `getAuthOptions()`
95
-
96
- Lower-level helper that returns `{ token }` or `{}` with proactive refresh. Use when you need the token but want to handle errors yourself.
97
-
98
- ## Cookie Management
99
-
100
- All cookie helpers are async (they use Next.js `cookies()` API):
101
-
102
- ```typescript
103
- import {
104
- // Cart
105
- getCartToken, getCartId, setCartCookies, clearCartCookies,
106
- getCartOptions, // { spreeToken, token } for cart SDK calls
107
- requireCartId, // throws if no cart
108
-
109
- // Auth
110
- getAccessToken, setAccessToken, clearAccessToken,
111
- getRefreshToken, setRefreshToken, clearRefreshToken,
112
- } from '@spree/next';
113
- ```
114
-
115
- ### Cart operations pattern
116
-
117
- ```typescript
118
- 'use server';
119
-
120
- import { getClient, getCartOptions, requireCartId } from '@spree/next';
121
-
122
- export async function updateCartItem(lineItemId: string, quantity: number) {
123
- const options = await getCartOptions();
124
- const cartId = await requireCartId();
125
- return getClient().carts.items.update(cartId, lineItemId, { quantity }, options);
126
- }
127
- ```
128
-
129
- ### Auth operations pattern
130
-
131
- ```typescript
132
- 'use server';
133
-
134
- import { getClient, setAccessToken, setRefreshToken, getCartToken, getCartId } from '@spree/next';
135
-
136
- export async function login(email: string, password: string) {
137
- const result = await getClient().auth.login({ email, password });
138
- await setAccessToken(result.token);
139
- await setRefreshToken(result.refresh_token);
140
-
141
- // Associate guest cart if one exists
142
- const cartToken = await getCartToken();
143
- const cartId = await getCartId();
144
- if (cartToken && cartId) {
145
- await getClient().carts.associate(cartId, {
146
- token: result.token,
147
- spreeToken: cartToken,
148
- }).catch(() => {}); // non-fatal
149
- }
150
-
151
- return { success: true, user: result.user };
152
- }
153
- ```
154
-
155
- ## Locale Resolution
156
-
157
- `getLocaleOptions()` reads country and locale from cookies (set by middleware or explicitly). All data-fetching server actions should use this:
158
-
159
- ```typescript
160
- 'use server';
161
-
162
- import { getClient, getLocaleOptions } from '@spree/next';
163
-
164
- export async function getProducts(params?: { limit?: number }) {
165
- const options = await getLocaleOptions();
166
- return getClient().products.list(params, options);
167
- }
168
-
169
- export async function getCategory(idOrPermalink: string) {
170
- const options = await getLocaleOptions();
171
- return getClient().categories.get(idOrPermalink, undefined, options);
172
- }
173
- ```
174
-
175
- ## Middleware
176
-
177
- Handles URL-based country/locale routing. Detects country from cookies, geo headers (Vercel/Cloudflare), or defaults, then redirects to `/{country}/{locale}/...`:
178
-
179
- ```typescript
180
- // middleware.ts
181
- import { createSpreeMiddleware } from '@spree/next/middleware';
182
-
183
- export default createSpreeMiddleware({
184
- defaultCountry: 'us',
185
- defaultLocale: 'en',
186
- });
187
-
188
- export const config = {
189
- matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\..*$).*)'],
190
- };
191
- ```
192
-
193
- ## Webhooks
194
-
195
- Handle Spree webhook events in your Next.js app with `@spree/next/webhooks`:
196
-
197
- ```typescript
198
- // src/app/api/webhooks/spree/route.ts
199
- import { createWebhookHandler } from '@spree/next/webhooks'
200
-
201
- export const POST = createWebhookHandler({
202
- secret: process.env.SPREE_WEBHOOK_SECRET!,
203
- handlers: {
204
- 'order.completed': async (event) => {
205
- await sendOrderConfirmationEmail(event.data)
206
- },
207
- 'order.canceled': async (event) => {
208
- await sendCancellationEmail(event.data)
209
- },
210
- 'order.shipped': async (event) => {
211
- await sendShippingNotification(event.data)
212
- },
213
- 'customer.password_reset_requested': async (event) => {
214
- await sendPasswordResetEmail(event.data)
215
- },
216
- },
217
- })
218
- ```
219
-
220
- The handler verifies HMAC-SHA256 signatures, rejects replayed requests, routes events to your handlers, and returns 200 immediately (handlers run async).
221
-
222
- ### Local development
223
-
224
- Webhooks require a publicly accessible URL. Use [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/) for local development:
225
-
226
- ```bash
227
- brew install cloudflared
228
- cloudflared tunnel --url http://localhost:3001
229
- ```
230
-
231
- Then create a webhook endpoint in **Spree Admin → Settings → Developers → Webhooks** pointing to your tunnel URL + `/api/webhooks/spree`.
232
-
233
- For more details, see [Webhooks](../../core-concepts/webhooks.md).
234
-
235
- ## TypeScript
236
-
237
- Import types directly from `@spree/sdk`:
238
-
239
- ```typescript
240
- import type {
241
- Product, Order, Cart, LineItem, Variant,
242
- Category, Country, Currency, Address, Customer,
243
- CreditCard, GiftCard, Fulfillment, DeliveryRate,
244
- Payment, PaymentSession, PaginatedResponse,
245
- AddressParams, SpreeError,
246
- } from '@spree/sdk';
247
- ```