Catalyst version 1.12.0 release notes
Catalyst 1.12.0 is a minor release. It serves the Universal Commerce Protocol (UCP) endpoints on the storefront’s public domain by proxying them to BigCommerce, and stops X-Correlation-ID from making every Next.js Data Cache lookup miss. For a full list of Catalyst changes, see the changeset on GitHub.
UCP endpoints on the storefront domain
Agents discover and call UCP on the storefront’s public domain, but the protocol is served by the BigCommerce platform rather than by Catalyst. Catalyst now proxies both UCP surfaces through to BigCommerce:
/.well-known/ucp— the discovery document. It was previously locale-redirected, like any other unmatched path./api/ucp/*— the checkout endpoints, for every HTTP method. These previously returned a 404.
Only the headers the UCP REST transport spec defines are passed in either direction, so nothing outside the spec is exchanged with a separate origin. No new environment variable is required.
Catalyst serves trailing-slash URLs, so the trailing slash is stripped before a UCP path is proxied. The platform answers a trailing slash with a 307 back to the bare path, which an agent resolves against the storefront domain and sends straight back, so the call would never land. Agents still follow Catalyst’s own trailingSlash redirect on the way in.
Upgrading a customized proxy
An unmodified proxy.ts picks up the UCP proxy with the rest of the upgrade. If you have customized it, make two changes:
- Add
withUcpProxyas the first argument tocomposeProxies. - Add
/api/ucp/:path*toconfig.matcher.
Correlation ID and the Next.js Data Cache
X-Correlation-ID is no longer sent on cacheable GraphQL requests, where it was making every Data Cache lookup miss.
The correlation ID is a fresh crypto.randomUUID() per request, memoized for the duration of a render by React.cache. Next.js builds its Data Cache key from the fetch URL, method, body, and headers, so a header that changes on every request produces a unique key on every request. Fetches configured with next: { revalidate } could therefore never hit: each one missed, went out to the BigCommerce GraphQL API, and wrote a new entry that nothing would ever read again. On a product page that is roughly 12 queries per page view, at the full uncached render cost every time, plus unbounded growth in the data cache.
Next.js already strips traceparent and tracestate from the cache key for this reason, but it can only do that for headers it knows about.
The correlation ID now follows the same rule as X-Forwarded-For and True-Client-IP in the same hook: it is attached only when fetchOptions.cache is no-store or no-cache. Those requests are uncacheable by construction, so there is no cache key to pollute, and they are the per-customer requests where a correlation ID is most useful for tracing. Cacheable requests now share a stable key and hit the Data Cache as intended.
Release tags
Latest stable: