Configuring Headers
This guide provides an overview on how to configure COOP/COEP headers, including hosting platform configuration.
WebContainers require that your page, even in development, is served with these two headers:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
These headers are needed because WebContainer requires SharedArrayBuffer, which, in turn, requires your website to be cross-origin isolated.
Some browsers support a different mode for cross-origin isolation: credentialless
. If you wish to serve your content in this way, set your headers instead to:
Cross-Origin-Embedder-Policy: credentialless
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: credentialless
Cross-Origin-Opener-Policy: same-origin
and make sure to boot your WebContainer specifying coep: 'credentialless'
.
Deep Dive: cross-origin isolation
Here are a few helpful resources if you'd like to learn more about these topics:
- MDN page on SharedArrayBuffer
- MDN page on cross-origin isolation
- our primer on COOP/COEP
- StackBlitz docs page on browser support
Cloudflare
All pages
You can configure headers for all pages in your _headers
file:
/*
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
/*
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your _headers
file:
/tutorial
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
/tutorial
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Netlify
All pages
You can configure headers for all pages in your netlify.toml
file:
[[headers]]
for = "/*"
[headers.values]
Cross-Origin-Embedder-Policy = "require-corp"
Cross-Origin-Opener-Policy = "same-origin"
[[headers]]
for = "/*"
[headers.values]
Cross-Origin-Embedder-Policy = "require-corp"
Cross-Origin-Opener-Policy = "same-origin"
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your netlify.toml
file:
[[headers]]
for = "/tutorial"
[headers.values]
Cross-Origin-Embedder-Policy = "require-corp"
Cross-Origin-Opener-Policy = "same-origin"
[[headers]]
for = "/tutorial"
[headers.values]
Cross-Origin-Embedder-Policy = "require-corp"
Cross-Origin-Opener-Policy = "same-origin"
Read more here about headers on Netlify.
Vercel
All pages
You can configure headers for all pages in your vercel.json
file:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}
]
}
]
}
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}
]
}
]
}
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your vercel.json
file:
{
"headers": [
{
"source": "/tutorial",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}
]
}
]
}
{
"headers": [
{
"source": "/tutorial",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}
]
}
]
}
Read more here about headers on Vercel.
Configuring across popular meta-frameworks
Sometimes, configuring headers in your meta-framework of choice is easier than configuring them in your hosting platform. Here are some guides for popular meta-frameworks:
SvelteKit
All pages
You can configure headers for all pages in your hooks.server.js
file:
export const handle = async ({ request, resolve }) => {
const response = await resolve(request);
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
return response;
};
export const handle = async ({ request, resolve }) => {
const response = await resolve(request);
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
return response;
};
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your hooks.server.js
file:
export const handle = async ({ request, resolve }) => {
const response = await resolve(request);
if (request.path === '/tutorial') {
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
}
return response;
};
export const handle = async ({ request, resolve }) => {
const response = await resolve(request);
if (request.path === '/tutorial') {
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
}
return response;
};
You can also do this in specific page's +page.server.js
file:
/** @type {import('./$types').PageServerLoad} */
export const load = ({ setHeaders }) => {
setHeaders({
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
});
};
/** @type {import('./$types').PageServerLoad} */
export const load = ({ setHeaders }) => {
setHeaders({
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
});
};
Nuxt 3
All pages
You can configure headers for all pages in your nuxt.config.js
file:
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
nitro: {
routeRules: {
'**': {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
},
},
},
});
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
nitro: {
routeRules: {
'**': {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
},
},
},
});
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your nuxt.config.js
file:
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
nitro: {
routeRules: {
'/tutorial': {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
},
},
},
});
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
nitro: {
routeRules: {
'/tutorial': {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
},
},
},
});
NextJS
All pages
You can configure headers for all pages in your next.config.js
file:
// https://nextjs.org/docs/api-reference/next.config.js/introduction
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
],
},
];
},
};
// https://nextjs.org/docs/api-reference/next.config.js/introduction
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
],
},
];
},
};
Specific page
You can configure headers for a specific page(/tutorial
in this case) in your next.config.js
file:
// https://nextjs.org/docs/api-reference/next.config.js/introduction
module.exports = {
async headers() {
return [
{
source: '/tutorial',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
],
},
];
},
};
// https://nextjs.org/docs/api-reference/next.config.js/introduction
module.exports = {
async headers() {
return [
{
source: '/tutorial',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
],
},
];
},
};