Skip to content

Postpone context creation #2240

@mdanilowicz

Description

@mdanilowicz

High volumes of bot and crawler traffic can cause excessive creation of sales_channel_api_context entries.
Currently, a context token is generated during page initialization, even if the visitor does not perform any action that actually requires a context.

As a result, crawlers that only fetch pages can trigger the creation of large numbers of unused contexts, leading to unnecessary database growth and potential performance issues.

Proposed Solution

Investigate whether the context token can be created lazily, only when it is actually required (e.g., when a request needs a valid sales channel context), instead of generating it during the initial page load.

Acceptance Criteria

  • Context tokens are not created automatically on page initialization.
  • Bot/crawler page requests that do not require a context do not generate new context entries.
  • Existing functionality that depends on the context remains unaffected.
  • Explain context token lifecycle in the documentation

Notes

The goal is to reduce unnecessary context creation caused by automated traffic while maintaining compatibility with existing frontends behavior.

Findings: Context token creation

The main trigger is templates/vue-starter-template/app/app.vue, where the app always calls:

apiClient.invoke("readContext get /context")

This happens before the visitor performs any session-dependent action. As a result, bots/crawlers that only request public pages can still cause context token creation.

A context token is not strictly required for the first frontend initialization. It is only required once the frontends needs session-specific behavior, for example:

  • cart operations
  • checkout
  • login/register/logout
  • customer account pages
  • changing language/currency/country
  • shipping/payment method changes
  • reading the full /context response for customer/session data

Public read-only pages such as CMS pages, product listings, product detail pages, navigation, and search should not need the frontend to explicitly initialize a user session.

Proposed solution

Introduce an opt-in lazy context mode, for example:

shopware: {
  sessionContext: {
    strategy: "eager" | "lazy"
  }
}

Default should remain eager for backward compatibility.

In lazy mode:

  • Do not call readContext get /context during global app initialization.
  • Do not globally refresh cart or synced wishlist on first page load.
  • Initialize useSessionContext() without session data.
  • Load/refresh session context only before session-dependent flows.
  • Avoid persisting anonymous context tokens from purely public read requests where possible.

This would reduce unnecessary context/session creation caused by crawler traffic while keeping existing frontend behavior available for interactive user flows.

⚠️ A complete solution may also require backend/Core support, for example a way to perform public read requests without generating or returning a persistent context token.

When do we actually need to fetch the context?

We should not treat context fetching as something that must always happen during the first frontends initialization.

The decision should be based on two things:

  1. Does the visitor already have an existing sw-context-token?
  2. Does the current UI or action actually need session-specific data?

If there is no existing sw-context-token, we can treat the visitor as having no known server-side session yet. In that case, we should avoid calling /context or /checkout/cart just to check whether something exists, because that request can itself create or adopt a new context token.

This is especially important for bots and crawlers. A crawler may only request public pages and never perform any cart, checkout, or account action. If we fetch the context on every initial page load, we create sessions for those visits even though they never need one.

For public, read-only pages, such as CMS pages, product listings, product detail pages, navigation, and search, the frontend should be able to render without explicitly initializing a user session.

A context should be fetched when the frontends needs session-specific data, for example:

  • login, register, logout
  • account pages
  • checkout
  • changing language, currency, country, shipping method, or payment method
  • reading customer/session information from /context

The cart should be handled separately. Fetching /context is not the right way to check whether the cart contains items. If the UI needs cart information, it should fetch /checkout/cart.

For cart restoration, the rule can be:

  • If there is an existing sw-context-token, fetch the cart when the UI needs an accurate cart count or cart contents.
  • If there is no existing sw-context-token, assume the cart is empty until the user performs a cart action, such as adding a product.

This means the behavior is not only about first-time visitors. It is about whether there is an existing session token. A returning visitor with a token can have their cart/session restored. A new anonymous visitor without a token should not trigger session creation just because the header cart badge wants to confirm that the cart is empty.

A possible lazy strategy would be:

const hasContextToken = Boolean(Cookies.get("sw-context-token"));

if (hasContextToken) {
  // Restore session/cart only when the current UI needs it.
} else {
  // Do not fetch context/cart during public page initialization.
  // Treat cart count as 0 until the user performs a session-dependent action.
}

This keeps existing interactive frontends behavior intact while avoiding unnecessary context creation for anonymous public page views.

Metadata

Metadata

Labels

No labels
No labels
No fields configured for Improvement.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions