Skip to content

Explain when a Commerce route answers with the app's HTML page - #1530

Open
sbolinger-godaddy wants to merge 1 commit into
mainfrom
storefront-non-json-api-errors
Open

sbolinger-godaddy wants to merge 1 commit into
mainfrom
storefront-non-json-api-errors

Conversation

@sbolinger-godaddy

@sbolinger-godaddy sbolinger-godaddy commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A template with no connected store showed Unexpected token '<', "<!doctype "... is not valid JSON in place of its catalog. Its server never mounted /api/commerce, so the SSR catch-all answered GET /api/commerce/config with index.html and a 200. The storefront only read the body of failed responses, so it passed the page to response.json().

  • A successful text/html response is now a failure. checkedFetch throws an ApiError with the new apiUnavailable text: "The store could not be reached. Please retry." in English and "La boutique est injoignable. Veuillez réessayer." in French. The check is in checkedFetch, so it covers every request() call and the cart's add path.
  • It never shows sample products. As the server contract requires, a missing route is an error, not unbound, so a connected store with a broken deployment never shows fake products.
  • Development builds name the route and the fix, once per route per page load, because configuration polling repeats the request:
    [gd-commerce-storefront] /api/commerce/config 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.
  • Docs:
    • The server README has a new section, "A site before its store connects". It covers createCommerceCatalogRouter, an explicit readConnectionState(), and mounting the routes before static and fallback routes.
    • The storefront README has a troubleshooting entry for this error.
    • The server API contract says a text/html success is treated as a failure.

The server example reads the connection state from an explicit setting. While fixing the template, an agent inferred unbound from a missing GODADDY_STORE_ID, which both packages forbid: a connected store that lost the variable would quietly show samples.

Screenshots

Before
before-catalog-json-error

After
after-catalog-unavailable

Changeset

  • Changeset added (@godaddy/gd-commerce-storefront patch). The server package changes are docs only.

Test Plan

  • Unit tests (Vitest), 2 new in storefront.test.tsx. Both fail without the change:
    • request() and addToCart turn an HTML 200 into an ApiError with apiUnavailable text, and the console message appears once per route.
    • The catalog shows the new message, never the parse error, and no samples.
  • pnpm --filter @godaddy/gd-commerce-storefront build, typecheck, lint and test pass (184 tests), and the example app builds.
  • Commerce component test app, with packed builds of main and this branch:
    • A new html-api check passes 5 of 5 on this branch and fails 5 of 5 on main. It covers the catalog, sample catalog, product page, retry once routes answer, and one console message per page load after more /config requests.
    • The existing suites pass on this branch: smoke 19, parts 13, walkthrough 5, french 5, boutique 4. Routine passes 4 of 5; its "template samples before a store connects" check fails the same way on main.

When a host never mounts /api/commerce, its single-page app or SSR fallback
answers with index.html and a 200, and the storefront showed a JSON parse
error: Unexpected token '<', "<!doctype "... is not valid JSON.

A successful text/html response is now a failure with readable text, "The
store could not be reached. Please retry.", in English and French. It never
shows sample products. Development builds log the route once and say where
to mount the Commerce routes. The server README shows the setup for a site
before its store connects, and the storefront README has a troubleshooting
entry for the error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sbolinger-godaddy
sbolinger-godaddy requested a review from a team as a code owner November 4, 2026 21:15
@changeset-bot

changeset-bot Bot commented Nov 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0c7f6cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@godaddy/gd-commerce-storefront Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant