Updated: September 30, 2026

Configuring CORS for Your P1 Site

CORS Configuration
Security


What is CORS and why does it matter for P1?

When a visitor's browser loads your Next.js site, the P1 editor makes requests to the P1 backend API from within the browser. Because your site and the P1 API are on different domains, the browser enforces Cross-Origin Resource Sharing (CORS) — a security mechanism that requires the API to explicitly declare which origins are allowed to make requests to it.

If CORS is not configured correctly for your domain, the browser will block every request the P1 editor makes, and the editor will fail to load.


Default behaviour: works out of the box

By default, the P1 API accepts requests from any origin. This means your site will work without any CORS configuration as soon as you integrate the P1 SDK.

In this default mode, the API responds with:

 Access-Control-Allow-Origin: *

This tells the browser that any domain may make requests. It is the correct starting point for most integrations.

Note on localhost: Requests from localhost and 127.0.0.1 (on any port) are always accepted. Your local development environment will work without any configuration.


Locking down to specific origins

If your security requirements call for restricting access to only your own domains, you can configure an explicit list of allowed origins for your site. Once you do this, the wildcard is replaced by your list — only the origins you configure will be accepted. To enable this, update your site's allowedOrigins via the P1 API:

PATCH https://ccr.p1.pantheon.io/api/sites/{your-site-id}
Authorization: Bearer {your-token}
Content-Type: application/json

{
  "allowedOrigins": [
    "https://www.mysite.com",
    "https://mysite.com"
  ]
}

Once configured, the API will respond with your specific origin and enable credentialed requests:

Access-Control-Allow-Origin: https://www.mysite.com
Access-Control-Allow-Credentials: true

Requests from any other origin will be blocked.

To revert to the default open behaviour, set allowedOrigins to an empty array:

{
  "allowedOrigins": []
}


Origin pattern syntax

Each entry in allowedOrigins must include the full protocol. Three formats are supported:

Format

Example

What it matches

Exact origin

https://www.mysite.com

Only that exact origin (protocol + hostname + optional port)

Subdomain wildcard

https://*.mysite.com

Any single-level subdomain: app.mysite.com, preview.mysite.com — but NOT a.b.mysite.com

Origin with port

https://mysite.com:8080

Only that exact origin and port combination

A few rules to keep in mind:

  • Each pattern must include the protocol (https:// or http://). Entries without a protocol are ignored.
  • Only one wildcard (*) per pattern is allowed. https://*.*.mysite.com is invalid.
  • The wildcard matches only a single DNS label — it will not match nested subdomains.
  • You can configure up to 50 patterns per site.
  • localhost and 127.0.0.1 are always accepted regardless of your configuration.


Propagation time

Changes to allowedOrigins take effect within approximately 5 minutes across all regions. If a change does not appear to have taken effect immediately, wait a few minutes and try again.


Common scenarios

My site runs on a custom domain

You do not need to configure allowedOrigins for your site to work — the default open behaviour will handle it. If you want to restrict access to only your domain, add it explicitly:

{
  "allowedOrigins": [
    "https://www.mysite.com",
    "https://mysite.com"
  ]
}

My site has multiple environments (production, preview, staging)

Add each environment's origin to the list. You can use a subdomain wildcard to cover Pantheon preview environments:

{
  "allowedOrigins": [
    "https://www.mysite.com",
    "https://*.mysite.com",
    "https://*.mysite.pantheonsite.io"
  ]
}

I want to use the default open behaviour (recommended for most sites)

No action required. The P1 SDK will work with your site out of the box.

I configured allowed origins and now the editor is broken

Check that the origin your browser is currently using — including the exact protocol and subdomain — is in your allowedOrigins list. A common issue is including https://mysite.com but not https://www.mysite.com (or vice versa). Also check that 5 minutes have passed since you made the change. If you need to recover immediately, reset to the open default by setting allowedOrigins to [].

CORS Configuration
Security