> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Catalyst version 1.13.1 release notes

> Catalyst 1.13.1 restricts the /graphql relay to wallet button operations, keeps tracking parameters out of the route cache key, stops analytics events for bots and other non-page requests, sets an explicit cache option on every GraphQL request, and forwards the shopper IP on more requests.

Catalyst 1.13.1 is a patch release. It reduces the requests a storefront sends to BigCommerce for bots and ad traffic, restricts the `/graphql` relay to the operations wallet buttons need, and forwards the shopper IP on more requests so BigCommerce can apply per-IP limits. For a full list of Catalyst changes, see the [changeset on GitHub](https://github.com/bigcommerce/catalyst/blob/canary/core/CHANGELOG.md#1131).

## GraphQL proxy limited to wallet button operations

The [GraphQL proxy](/developer/docs/storefront/catalyst/development/middleware#with-graphql-proxy) lets `checkout-sdk-js` call the GraphQL Storefront API through the storefront domain to render wallet buttons. It used to relay any query or mutation sent with the `x-catalyst-graphql-proxy-requester` header, and anyone can set that header.

The proxy now parses each request and forwards it only when it is exactly one of the mutations `checkout-sdk-js` sends for wallet buttons:

| Operation                              | Root field                                        |
| :------------------------------------- | :------------------------------------------------ |
| `CreatePaymentWalletIntentMutation`    | `payment.paymentWallet.createPaymentWalletIntent` |
| `AddCheckoutBillingAddressMutation`    | `checkout.addCheckoutBillingAddress`              |
| `UpdateCheckoutBillingAddressMutation` | `checkout.updateCheckoutBillingAddress`           |
| `CheckoutRedirectMutation`             | `cart.createCartRedirectUrls`                     |

The operation type, name, and root field path must all match, and the document must contain a single operation. Anything else gets a `403`, and a body that isn't valid JSON or has no query gets a `400`. Requests without the header continue down the proxy chain as before. Relayed requests now forward the shopper IP.

## Tracking parameters share the route cache

The `withRoutes` proxy resolves each URL with a GraphQL route lookup and caches the result in the KV store. The cache key included the full query string, so every unique `utm_source` or click ID was a cache miss and a blocking request to BigCommerce, and ad traffic bypassed the cache.

Tracking parameters are now removed from the lookup and the cache key: every parameter that starts with `utm_`, plus `_branch_match_id`, `_ga`, `_gl`, `_hsenc`, `_hsmi`, `_kx`, `dclid`, `epik`, `fbclid`, `gad_campaignid`, `gad_source`, `gbraid`, `gclid`, `gclsrc`, `igshid`, `irclickid`, `li_fat_id`, `mc_cid`, `mc_eid`, `mkt_tok`, `msclkid`, `rdt_cid`, `sccid`, `srsltid`, `ttclid`, `twclid`, `wbraid`, and `yclid`. Other parameters keep their original order, because BigCommerce matches redirect sources against the query string as written.

Pages and redirects still receive the original query string. When a 301 redirect matches on a query parameter, the tracking parameters are carried over to the target.

> **Warning**
>
> A 301 redirect whose source matches on a tracking parameter, such as `/old?utm_campaign=spring`, no longer matches. Match on the path or on a parameter that isn't a tracking parameter instead.

## Analytics events only for page navigations

The proxy used to send a `VisitStarted` mutation for every request without visit cookies, and `ProductViewed` on the first product view of a visit. Bots and scripts rarely keep cookies, so each of their requests cost one or two uncached mutations.

Catalyst now sends these events only for requests that look like a page load in a browser. A request is skipped when any of the following is true:

* The `User-Agent` is empty, or the [`isbot`](https://www.npmjs.com/package/isbot) package identifies it as a bot, crawler, or script client.
* `Sec-Fetch-Mode` is present and isn't `navigate`, or `Sec-Fetch-Dest` is present and isn't `document`.
* Neither fetch metadata header is present and `Accept` doesn't include `text/html`.

A skipped request gets no visit cookie, so the next real page load still starts a visit. Visits that already exist keep their cookies refreshed on every request. Consent handling and [`DISABLE_ANALYTICS`](/developer/docs/storefront/catalyst/reference/environment-variables#disable_analytics) are unchanged.

## Explicit cache options

The root layout sets `fetchCache = 'default-cache'`, so a GraphQL request under `[locale]` with no cache option was stored in the Data Cache with no expiry. Every `client.fetch` call now passes an explicit option:

* **Shared reads** revalidate with [`DEFAULT_REVALIDATE_TARGET`](/developer/docs/storefront/catalyst/reference/environment-variables#default_revalidate_target), 1 hour by default. A changed maintenance message now shows within that window, and the gift certificate settings and favicon refresh the same way.
* **Mutations and per-customer reads** use `cache: 'no-store'`, so they forward the shopper IP. This covers changing a password, newsletter subscribe and unsubscribe, and switching the cart currency or locale.

Switching back to the store's default currency now clears the currency cookie, so a cookie set to the default no longer creates a second cache entry for the same data.

## Legacy password reset links

When a customer is flagged with "Request customer to set their password on next login", BigCommerce emails a link in the legacy Stencil format, `/login?action=change_password&c=<id>&t=<token>`. The login page ignored those parameters. It now forwards the link to `/change-password`, so the customer can set a new password.

## Shopper IP forwarding

* **UCP proxy**: requests relayed to `/.well-known/ucp` and `/api/ucp/*` now send the caller's IP as `X-Forwarded-For` and `True-Client-IP`, as the GraphQL client already does.
* **Route and storefront status lookups**: the proxy's lookups now use `cache: 'no-store'`. They were never stored in the Data Cache, because the KV store is their cache, so the only change is that they forward the shopper IP.

## Route cache warning

Without a shared KV store, the route cache falls back to per-instance memory, and every instance and cold start repeats the route, storefront status, and locale lookups. Catalyst now logs a warning once per process in production when this happens.

> **Info**
>
> **Route caching on Storefront Hosting and Vercel**
>
> Route caching works out of the box on both documented hosts, with no external KV store or extra configuration:
>
> * **Storefront Hosting:** each project gets its own Cloudflare Workers KV namespace, bound to the deployment automatically.
> * **Vercel:** route caching uses the [Vercel Runtime Cache](https://vercel.com/changelog/introducing-the-runtime-cache-api).
>
> On any other host, set [`UPSTASH_REDIS_REST_URL`](/developer/docs/storefront/catalyst/reference/environment-variables#upstash_redis_rest_url) and [`UPSTASH_REDIS_REST_TOKEN`](/developer/docs/storefront/catalyst/reference/environment-variables#upstash_redis_rest_token) to cache routes in [Upstash](https://upstash.com/). Without one of these, route data is cached only in memory, which isn't shared across server instances, and Catalyst logs a warning in production.

## Migration

No migration steps are required, and no environment variables were added or renamed.

Review these behavior changes when you upgrade:

* **Redirects on tracking parameters**: 301 redirects whose source matches on a tracking parameter no longer match.
* **Other libraries on the GraphQL proxy**: a client-side library you added to `ALLOWED_REQUESTERS` now gets a `403` unless its operations are added to `core/lib/graphql-proxy/wallet-operations.ts`.
* **Analytics**: visit counts no longer include bots, crawlers, scripts, headless browsers, or synthetic monitors.

If you customized any of these files, review the changes. The [changeset on GitHub](https://github.com/bigcommerce/catalyst/blob/canary/core/CHANGELOG.md#1131) has the code for each one.

* **GraphQL proxy**: `core/proxies/with-graphql-proxy.ts` uses the new `core/lib/graphql-proxy/wallet-operations.ts`.
* **Routes**: `core/proxies/with-routes.ts` uses the new `core/lib/routes/route-lookup-search.ts`, and its route and storefront status lookups use `cache: 'no-store'`.
* **Analytics**: `core/proxies/with-analytics-cookies.ts` and `core/proxies/with-routes.ts` use the new `core/lib/analytics/is-interactive-request.ts`, which adds the `isbot` dependency.
* **GraphQL client**: `beforeRequest` moved from `core/client/index.ts` to `core/client/before-request.ts`, with no behavior change. `core/lib/currency.ts` clears the currency cookie when the default currency is selected.
* **Login**: `core/app/[locale]/(default)/(auth)/login/page.tsx` handles the `action`, `c`, and `t` search parameters.
* **UCP proxy**: `core/lib/ucp/upstream.ts` forwards the client IP.
* **KV store**: `core/lib/kv/index.ts` logs the memory fallback warning.

## Release tags

* [**@bigcommerce/catalyst-core@1.13.1**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-core%401.13.1)
* [**@bigcommerce/catalyst-makeswift@1.13.1**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-makeswift%401.13.1)
* [**@bigcommerce/catalyst-b2b-makeswift@1.13.1**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-b2b-makeswift%401.13.1)

Latest stable:

* [**@bigcommerce/catalyst-core@latest**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-core%40latest)
* [**@bigcommerce/catalyst-makeswift@latest**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-makeswift%40latest)
* [**@bigcommerce/catalyst-b2b-makeswift@latest**](https://github.com/bigcommerce/catalyst/releases/tag/%40bigcommerce%2Fcatalyst-b2b-makeswift%40latest)