Configuring CORS
Cross-Origin Resource Sharing (CORS) controls which websites can access your GraphQL API from a browser. Without proper CORS configuration, legitimate web apps can’t reach your API, but with overly permissive settings, you’re opening the door to unwanted access.
This guide shows you how to set up CORS for real-world scenarios. For the complete configuration
reference, see cors configuration.
How CORS Works
When a web page tries to make a request to your API from a different domain, the browser checks CORS rules first:
- Browser sends preflight request (for certain types of requests)
- Router responds with allowed origins, methods, and headers
- Browser allows or blocks the actual request based on the response
The router uses a policy-based system where you define rules for different origins. When a request comes in, it finds the first matching policy and applies those rules.
Basic Setup: Single Web App
The most common scenario is allowing your web application to access the API.
What you want:
- Production website can access the API
- Local development environment works too
- Block everyone else
cors:
  enabled: true
  policies:
    - origins:
        - https://my-app.com
        - http://localhost:3000
      methods:
        - GET
        - POST
        - OPTIONS
      allow_headers:
        - Content-Type
        - AuthorizationThis allows your production site and local dev server to make requests, while blocking all other origins.
Handling Credentials
By default, browsers don’t send cookies or authentication headers in cross-origin requests. You need to explicitly allow this.
cors:
  enabled: true
  allow_credentials: true # Allow cookies and auth headers
  policies:
    - origins:
        - https://my-app.com
      methods:
        - GET
        - POST
        - OPTIONS
      allow_headers:
        - Content-Type
        - AuthorizationImportant: When you enable allow_credentials, you cannot use wildcards for origins. You must
specify exact domains.
Different Rules for Different Origins
Sometimes you need different CORS rules for different types of clients.
cors:
  enabled: true
  # Default settings for most origins
  allow_credentials: false
  methods: ['GET', 'POST', 'OPTIONS']
  allow_headers: ['Content-Type']
 
  policies:
    # Your main application - inherits defaults but adds credentials
    - origins:
        - https://my-app.com
      allow_credentials: true
      allow_headers:
        - Content-Type
        - Authorization
 
    # Partner integration - more permissive headers
    - origins:
        - https://partner.example.com
      allow_headers:
        - Content-Type
        - Authorization
        - X-Partner-Token
        - X-API-Version
 
    # Public demo site - very restricted
    - origins:
        - https://demo.my-app.com
      methods: ['GET', 'OPTIONS'] # Read-only accessCommon Issues and Solutions
CORS is a common source of headaches. Here’s a quick guide to troubleshooting the most frequent problems.
“CORS error” in browser console:
- Check that your origin is listed in the CORS policy
- Verify the request method is allowed
- Make sure required headers are in the allow_headerslist
Preflight requests failing:
- Ensure OPTIONSis in yourmethodslist
- Check that Access-Control-Request-Headersmatch yourallow_headers
Credentials not being sent:
- Set allow_credentials: truein your policy
- Make sure your frontend code sets credentials: 'include'
- Cannot use wildcard origins when credentials are enabled
CORS works locally but not in production:
- Check that your production domain is in the origins list
- Make sure the router is accessible from your production environment