Para SDK works out of the box when your application doesn’t have a Content Security Policy (CSP). However, if your application has implemented a CSP for security purposes, you’ll need to add specific directives to ensure Para SDK functions properly. This guide covers how to configure CSP for both Next.js and Vite applications.

Required CSP Directives

If your application has a CSP policy in place, you’ll need to include the following directives for Para SDK:
CSP Directives
# Script sources (for SDK initialization)
script-src 'https://*.getpara.com' 'https://*.usecapsule.com';

# Worker sources (required for blob workers)
worker-src 'blob:' 'https://*.getpara.com' 'https://*.usecapsule.com';

# Connect sources (API calls and websockets)
connect-src 'https://*.getpara.com' 'https://*.usecapsule.com' 'wss://*.getpara.com' 'wss://*.usecapsule.com' 'https://*.ingest.sentry.io' 'https://*.ingest.us.sentry.io';

# Frame sources (for embedded content)
frame-src 'https://*.getpara.com' 'https://*.usecapsule.com';
No CSP configuration is needed if your application doesn’t currently implement a Content Security Policy. These directives are only required when you have an existing CSP that would otherwise block Para SDK’s functionality.
If you do have a CSP policy, the 'blob:' directive in worker-src is critical for Para SDK to function properly. It allows the SDK to create and execute web workers from blob URLs.

Next.js Configuration

The following configurations are only needed if your Next.js application already has a CSP policy that needs to be updated to support Para SDK.

App Router

For Next.js App Router with existing CSP headers, update your next.config.js:
next.config.js
const nextConfig = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: [
              "default-src 'self'",
              "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.getpara.com https://*.usecapsule.com",
              "worker-src 'self' blob: https://*.getpara.com https://*.usecapsule.com",
              "connect-src 'self' https://*.getpara.com https://*.usecapsule.com wss://*.getpara.com wss://*.usecapsule.com https://*.ingest.sentry.io https://*.ingest.us.sentry.io",
              "frame-src 'self' https://*.getpara.com https://*.usecapsule.com",
              "style-src 'self' 'unsafe-inline'",
              "img-src 'self' data: https:",
              "font-src 'self' data:"
            ].join('; ')
          }
        ]
      }
    ]
  }
}

module.exports = nextConfig

Pages Router with Middleware

For more dynamic CSP configuration, use Next.js middleware:
middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const response = NextResponse.next()
  
  const csp = [
    "default-src 'self'",
    "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.getpara.com https://*.usecapsule.com",
    "worker-src 'self' blob: https://*.getpara.com https://*.usecapsule.com",
    "connect-src 'self' https://*.getpara.com https://*.usecapsule.com wss://*.getpara.com wss://*.usecapsule.com https://*.ingest.sentry.io https://*.ingest.us.sentry.io",
    "frame-src 'self' https://*.getpara.com https://*.usecapsule.com",
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "font-src 'self' data:"
  ].join('; ')
  
  response.headers.set('Content-Security-Policy', csp)
  
  return response
}

export const config = {
  matcher: '/:path*'
}

Vite Configuration

The following configurations are only needed if your Vite application already has a CSP policy that needs to be updated to support Para SDK. For Vite applications with existing CSP, you can use the vite-plugin-csp plugin:
Installation
npm install -D vite-plugin-csp
vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import csp from 'vite-plugin-csp'

export default defineConfig({
  plugins: [
    react(),
    csp({
      policy: {
        'default-src': ["'self'"],
        'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'", 'https://*.getpara.com', 'https://*.usecapsule.com'],
        'worker-src': ["'self'", 'blob:', 'https://*.getpara.com', 'https://*.usecapsule.com'],
        'connect-src': ["'self'", 'https://*.getpara.com', 'https://*.usecapsule.com', 'wss://*.getpara.com', 'wss://*.usecapsule.com', 'https://*.ingest.sentry.io', 'https://*.ingest.us.sentry.io'],
        'frame-src': ["'self'", 'https://*.getpara.com', 'https://*.usecapsule.com'],
        'style-src': ["'self'", "'unsafe-inline'"],
        'img-src': ["'self'", 'data:', 'https:'],
        'font-src': ["'self'", 'data:']
      }
    })
  ]
})

Alternative: Meta Tag Configuration

If your Vite application uses a meta tag for CSP, update your index.html:
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.getpara.com https://*.usecapsule.com; worker-src 'self' blob: https://*.getpara.com https://*.usecapsule.com; connect-src 'self' https://*.getpara.com https://*.usecapsule.com wss://*.getpara.com wss://*.usecapsule.com https://*.ingest.sentry.io https://*.ingest.us.sentry.io; frame-src 'self' https://*.getpara.com https://*.usecapsule.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;">
    <title>Your App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

Development vs Production

For development environments, you may need to add 'unsafe-eval' to script-src for hot module replacement. Ensure this is removed in production builds.

Development CSP

Development Configuration
const isDevelopment = process.env.NODE_ENV === 'development'

const cspDirectives = {
  'script-src': [
    "'self'",
    "'unsafe-inline'",
    isDevelopment && "'unsafe-eval'", // Only in development
    'https://*.getpara.com',
    'https://*.usecapsule.com'
  ].filter(Boolean)
}

Next Steps