@godaddy/gd-commerce-storefront 0.11.0 → 0.11.1

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.
package/README.md CHANGED
@@ -512,6 +512,16 @@ Cart mutations share one queue, including initial cart creation. The cart ID is
512
512
 
513
513
  Changing the server-provided cart scope resets cart state and prevents old responses from affecting the new connection. A failed configuration refresh temporarily disables commerce and also invalidates pending responses. Normal configuration loading and failures do not unmount host content.
514
514
 
515
+ ## Troubleshooting
516
+
517
+ **"The store could not be reached" with `returned an HTML page instead of JSON` in the console.** A request under
518
+ `/api/commerce` got the application's HTML page. The Commerce routes are not mounted on this origin, or a static
519
+ file, single-page app or SSR fallback route answers before them. Mount them at `/api/commerce` ahead of those
520
+ routes; with a separate API server in development, proxy `/api/commerce` to it. Opening `/api/commerce/config` in
521
+ the browser should return JSON. A missing route never shows sample products, even with `sampleProducts`: the server
522
+ must report `state: 'unbound'`. See [Before a store is connected](#before-a-store-is-connected) and the server
523
+ package's [example for a site before its store connects](../commerce-server/README.md#a-site-before-its-store-connects).
524
+
515
525
  ## Guides
516
526
 
517
527
  - [Server API contract](docs/server-api.md)
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as StorefrontMessages, i as StorefrontMessageKey, n as MessageValues, o as enUS, r as StorefrontMessage, s as formatMessage, t as CommerceErrorCode } from "./messages-CHl-bWx9.js";
1
+ import { a as StorefrontMessages, i as StorefrontMessageKey, n as MessageValues, o as enUS, r as StorefrontMessage, s as formatMessage, t as CommerceErrorCode } from "./messages-peJIfMO4.js";
2
2
  import { CSSProperties, ReactElement, ReactNode } from "react";
3
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ const englishText = {
14
14
  requestFailed: "Commerce request failed. Please retry.",
15
15
  requestFailedStatus: "Commerce request failed ({status}). Please retry.",
16
16
  requestTimeout: "Commerce information took too long to load. Please retry.",
17
+ apiUnavailable: "The store could not be reached. Please retry.",
17
18
  unknownError: "Something went wrong. Please retry.",
18
19
  storageUnavailable: "Your browser cannot save the cart. Keep this page open while shopping.",
19
20
  invalidAddItem: "Select a product variant and a positive quantity.",
@@ -219,8 +220,22 @@ var ApiError = class extends Error {
219
220
  this.text = options?.text;
220
221
  }
221
222
  };
223
+ const warnedHtmlPaths = /* @__PURE__ */ new Set();
224
+ function warnHtmlResponse(input) {
225
+ if (process.env.NODE_ENV === "production") return;
226
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
227
+ const path = url.split(/[?#]/)[0] ?? url;
228
+ if (warnedHtmlPaths.has(path)) return;
229
+ warnedHtmlPaths.add(path);
230
+ console.error(`[gd-commerce-storefront] ${path} returned an HTML page instead of JSON. Mount the commerce routes at /api/commerce on this origin, before any static file or single-page app fallback route.`);
231
+ }
222
232
  const checkedFetch = async (input, init) => {
223
233
  const response = await fetch(input, init);
234
+ if (response.status < 500 && /^\s*text\/html\b/i.test(response.headers.get("Content-Type") ?? "")) {
235
+ warnHtmlResponse(input);
236
+ const text = { key: "apiUnavailable" };
237
+ throw new ApiError(formatMessage(enUS, text.key), 502, { text });
238
+ }
224
239
  if (!response.ok) {
225
240
  const data = await response.text();
226
241
  const parsed = (() => {
@@ -1,4 +1,4 @@
1
- import { a as StorefrontMessages } from "../messages-CHl-bWx9.js";
1
+ import { a as StorefrontMessages } from "../messages-peJIfMO4.js";
2
2
 
3
3
  //#region src/locales/fr-fr.d.ts
4
4
  /** The package's text in French (France). Pass it to `CommerceProvider` as `messages`, with `locale='fr-FR'`. */
@@ -20,6 +20,7 @@ const frFR = {
20
20
  requestFailed: "La requête a échoué. Veuillez réessayer.",
21
21
  requestFailedStatus: "La requête a échoué ({status}). Veuillez réessayer.",
22
22
  requestTimeout: "Le chargement des informations a pris trop de temps. Veuillez réessayer.",
23
+ apiUnavailable: "La boutique est injoignable. Veuillez réessayer.",
23
24
  unknownError: "Un problème est survenu. Veuillez réessayer.",
24
25
  storageUnavailable: "Votre navigateur ne peut pas enregistrer le panier. Gardez cette page ouverte pendant vos achats.",
25
26
  invalidAddItem: "Sélectionnez une variante du produit et une quantité positive.",
@@ -15,6 +15,7 @@ declare const englishText: {
15
15
  requestFailed: string;
16
16
  requestFailedStatus: string;
17
17
  requestTimeout: string;
18
+ apiUnavailable: string;
18
19
  unknownError: string;
19
20
  storageUnavailable: string;
20
21
  invalidAddItem: string;
@@ -9,7 +9,7 @@ Server implementations can use GoDaddy Commerce APIs or their existing integrati
9
9
  - Requests use same-origin browser credentials. JSON writes set `Content-Type: application/json`.
10
10
  - Cart, catalog and checkout requests include `X-Commerce-Scope` from `/config`. Validate that scope against the server's current store/channel binding, especially before writes. Treat it as a stale-binding guard, not authorization. Authenticate and authorize requests independently.
11
11
  - Read requests use `cache: no-store`, cancellation, and a 15-second timeout. The initial cart creation/add request is also a write and is never retried automatically.
12
- - Return a non-2xx response with `{ "error": "A useful customer-facing message" }` for failure. HTML error pages are also handled as failures.
12
+ - Return a non-2xx response with `{ "error": "A useful customer-facing message" }` for failure. HTML error pages are also handled as failures. A `text/html` response below 500, such as a single-page app fallback or an HTML 404 page answering an unmounted route, is reported as "The store could not be reached" with status 502, so it never clears a saved cart.
13
13
  - Only cart reads with HTTP 404 or 410 clear an expired saved cart. Network errors, 401/403/409/5xx, and other failures preserve the ID and block writes until hydration succeeds.
14
14
  - Resolve prices and availability on the server. The cart does not calculate shipping, taxes, or discounts; it explains that they are calculated at checkout. Browser SKU names and quantities are input, not pricing authority. Protect mutations against CSRF as appropriate for the host application's authentication.
15
15
 
@@ -31,7 +31,9 @@ Server implementations can use GoDaddy Commerce APIs or their existing integrati
31
31
 
32
32
  `/checkout` is required only when checkout is enabled. `/discounts` is needed if the host uses `applyDiscount`. The standard catalog/detail/cart flow uses the other routes. All product/cart IDs in request paths are encoded.
33
33
 
34
- The companion `@godaddy/gd-commerce-server` returns 404 from product details when the group is missing or excluded by the catalog's ACTIVE filter, including direct links to inactive products.
34
+ The companion `@godaddy/gd-commerce-server` filters `GET /products` to ACTIVE groups available on the server-configured channel. It returns 404 from `GET /products/:id` when the group is missing, inactive, or unavailable on that channel, including direct product links. Browser callers cannot override the configured channel. This browsing filter does not check product-channel eligibility for `GET /skus/:id`, cart creation, or item addition by SKU ID; hosts must enforce any required restrictions on those operations. See the [server package's channel visibility notes][server-channel-visibility] for stale-channel troubleshooting and upstream lookup costs.
35
+
36
+ [server-channel-visibility]: ../../commerce-server/README.md#product-channel-visibility
35
37
 
36
38
  ## Configuration
37
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godaddy/gd-commerce-storefront",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "Opinionated React storefront templates for GoDaddy Commerce",
5
5
  "type": "module",
6
6
  "license": "MIT",