· Iren Saltali · education · 2 min read

Why CORS Breaks SPAs and How to Fix It at the Gateway

A plain-language explanation of why browser preflight fails and how to handle it centrally with the current CORS implementation.

The short answer: Most CORS pain comes from inconsistent origin, method, and header handling across services; centralizing it in the gateway removes that drift.

When to read this

  • A browser app talks to several APIs or Worker-backed services.
  • You keep seeing failing OPTIONS requests.
  • You want one CORS policy instead of many service-specific ones.

What matters in practice

  • Preflight should be predictable, not delegated to each backend.
  • Only allow the origins and headers your clients actually use.
  • Add an explicit OPTIONS route only when you need custom behavior.

Concrete example

        {
        "cors": {
          "allow_origins": ["https://app.example.com"],
          "allow_methods": ["GET", "POST", "OPTIONS"],
          "allow_headers": ["Authorization", "Content-Type"],
          "expose_headers": ["X-Request-Id"],
          "allow_credentials": true,
          "max_age": 300
        }
      }

The example above is intentionally small because the best gateway configs stay readable. Add only the route, auth, and mapping behavior you actually need.

How this maps to the current gateway

The current codebase already supports the behavior discussed here through its config schema, route matcher, and integration handlers. That is why this project is a good fit for reader-first examples: the docs and blog can point to real, implemented behavior instead of hypothetical gateway features.

What this product does not do

  • CORS solves browser cross-origin rules, not authentication or authorization.
  • Very permissive CORS settings still create security and debugging debt.

FAQ

Why do non-browser tools work while the SPA fails?

Because CORS is enforced by browsers, not by curl or server-side clients.

Do I need to define OPTIONS for every route?

No. The gateway already handles preflight when CORS is configured, unless you need a custom OPTIONS handler.

Last reviewed: March 6, 2026

Back to Blog

Related Posts

View All Posts »