Docs  /  Sandbox CSP

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:;

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

Stuck? Email support@useincito.com with your sandbox URL. We inspect the headers and reply with the exact diff.