Using Live Preview with an Alternate Control Panel Domain
Craft automatically sets Content-Security-Policy
and X-Frame-Options
headers for control panel requests, but doesn’t for front-end requests—including live preview.
If you access the Craft CMS control panel from its own separate domain or subdomain, you may need to send special response headers from your front-end to avoid “Refused to display” errors in your browser.
Recommended Headers #
Our Securing Craft article includes some recommendations for headers that harden sites accessed and managed from a single domain. In these cases, live preview will work exactly as expected, but can benefit from restricting the frame-ancestors
directive:
Content-Security-Policy: frame-ancestors 'self'
When your control panel is accessed from a different domain, it will need to be explicitly allowed, as self
would be too restrictive:
Content-Security-Policy: frame-ancestors 'self' https://control-panel.domain
Configuration Options #
You can send these Content-Security-Policy
headers directly from your HTTP server, or (as of Craft 5.3) via application configuration:
use craft\filters\Headers;
use craft\helpers\App;
return [
// Attach the headers filter to the application:
'as headersFilter' => [
'class' => Headers::class,
'headers' => [
'Content-Security-Policy' => join(' ', [
'frame-ancestors',
"'self'",
App::env('CRAFT_BASE_CP_URL'),
]),
],
],
];
Your control panel URL must come from an environment variable, as application configuration is evaluated prior to general config being populated.
Presuming you have configured a baseCpUrl
, the equivalent HTTP header can be sent from any Twig context with the {% header %}
tag:
{# _layout.twig #}
{% header "Content-Security-Policy: frame-ancestors 'self' #{craft.app.config.general.baseCpUrl}" %}
Note that in both contexts, the single-quotes around self
are required!
Further Reading #
- How to Access the Control Panel from a Subdomain
- Stack Exchange: Refused to display/connect when previewing entry on multi-site setup
- Using Live Preview Across Multiple Subdomains (Legacy information for prior versions of the live preview system)