Integration guide

Sandbox CSP setup

Add frame-ancestors https://app.useincito.com to your sandbox's Content-Security-Policy so the Incito magic-click iframe loads. Snippets for Next.js, Express, Django, Rails, Nginx, and Cloudflare.

Why this matters

Incito's hosted demo landing embeds your sandbox in an iframe so visitors get the full in-page tour with audio without leaving the launch page. That iframe needs your sandbox CSP to allow app.useincito.com as an embedder. This is the same B2B onboarding step Intercom Tours, Navattic, and Supademo require.

The one line you need

Add this directive to the Content-Security-Policy header on your sandbox route. Existing CSP entries stay; we're only adding frame-ancestors.

Content-Security-Policy directive
frame-ancestors 'self' https://app.useincito.com

Also remove X-Frame-Options. If your sandbox sets X-Frame-Options: SAMEORIGIN (Next.js default, Helmet default, Django SecurityMiddleware default), browsers honor that first and ignore your CSP frame-ancestors. Both must agree.

Pick your framework

App Router or Pages Router — same next.config.js config. The source path matches whichever route serves your sandbox demo.

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/demo/:path*',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: "frame-ancestors 'self' https://app.useincito.com",
          },
        ],
      },
    ];
  },
};

If you use a Next.js middleware that already sets a CSP header, merge the frame-ancestors directive into the existing policy rather than letting both compete.

Verify the fix

Two-step check from your terminal. The first line confirms your CSP carries the directive; the second line confirms X-Frame-Options is gone (or absent).

verify.sh
# Replace with your sandbox URL.
SANDBOX_URL="https://app.yourdomain.com/demo"

curl -sI "$SANDBOX_URL" | grep -i 'content-security-policy'
# Expected: ...; frame-ancestors 'self' https://app.useincito.com; ...

curl -sI "$SANDBOX_URL" | grep -i 'x-frame-options'
# Expected: (no output — header absent)

Or open your demo's Health page in the Incito dashboard at app.useincito.com — the iframe-ready badge there reflects the same probe and updates within minutes of your CSP change going live.

Common gotchas

  • CDN preprocessing. Cloudflare and Fastly can inject their own CSP. Disable their CSP injection on the demo route or merge our directive into theirs.
  • Nonces. If your CSP uses script nonces ('nonce-...'), frame-ancestors doesn't care — nonces apply only to script-src and style-src.
  • Cookie SameSite. If your sandbox auth uses SameSite=Strict, cookies drop inside the iframe. Use Lax or None; Secure on cookies the demo route reads.
  • Multiple CSP headers. If your stack emits CSP from two layers (origin plus reverse proxy), browsers combine them by intersection — a stricter directive in one layer overrides a permissive one in another. Audit both.

Still stuck

Email support@useincito.com with your sandbox URL. We'll probe it from our side and reply with the exact directive that's missing — usually under 24 hours.

← Back to setup walkthrough