Sandbox CSP
The exact Content-Security-Policy headers your sandbox route needs so Incito's widget can iframe-mount cleanly. Worked examples for Next.js, Cloudflare Pages, and Vercel.
Why CSP matters
The widget loads inside an iframe on your sandbox route during the demo. Browsers refuse to render an iframe whose frame-ancestors directive doesn't permit the parent. If your CSP is too strict, the demo loads as a blank rectangle. If it's too loose, you fail your security review. This page gives you the exact-fit policy.
Required directives
Your sandbox route's response headers must include the following:
frame-ancestors 'self' https://useincito.com https://app.useincito.com;
connect-src 'self' https://api.useincito.com wss://api.useincito.com;
script-src 'self' https://api.useincito.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
frame-ancestors— permits the dashboard and marketing origins to embed the sandbox.connect-src— covers HTTP and WebSocket calls to the Incito API.script-src— where the widget bundle lives.style-src— the widget injects an inline stylesheet.img-src— icons, persona avatars, screenshot fallbacks.
Next.js (App Router)
Add the headers in next.config.ts:
headers: async () => [
{
source: '/demo/:path*',
headers: [{
key: 'Content-Security-Policy',
value:
"frame-ancestors 'self' https://useincito.com https://app.useincito.com; " +
"connect-src 'self' https://api.useincito.com wss://api.useincito.com; " +
"script-src 'self' https://api.useincito.com; " +
"style-src 'self' 'unsafe-inline'; " +
"img-src 'self' data: https:;"
}]
}
]
Cloudflare Pages
Add a _headers file at the project root:
/demo/*
Content-Security-Policy: frame-ancestors 'self' https://useincito.com https://app.useincito.com; connect-src 'self' https://api.useincito.com wss://api.useincito.com
Vercel
Vercel honours headers in vercel.json. Same shape as the Next.js example; scope the source pattern to /demo/(.*).
{
"headers": [{
"source": "/demo/(.*)",
"headers": [{
"key": "Content-Security-Policy",
"value": "frame-ancestors 'self' https://useincito.com https://app.useincito.com; connect-src 'self' https://api.useincito.com wss://api.useincito.com"
}]
}]
}
Verifying
From the dashboard, paste the sandbox URL. The verifier probes the route from our backend, parses the headers, and tells you exactly which directive is missing. Most failures are frame-ancestors not including https://useincito.com or https://app.useincito.com.
Strict-mode option
If your security team wants the tightest possible policy, drop https://useincito.com from frame-ancestors. Only the dashboard origin needs to iframe the sandbox during a live demo. Everything else continues to work.
Common pitfalls
- Setting
frame-ancestors 'none'on the sandbox route — this blocks all iframing and the demo loads blank. - Missing
wss://inconnect-src— the agent's WebSocket session can't open and Q&A is silent. - Using
X-Frame-Options: DENYalongside CSP — the deprecated header overrides modernframe-ancestorsin some browsers; remove it.