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:
# 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
:
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:
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:
npm install -D vite-plugin-csp
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:']
}
})
]
})
If your Vite application uses a meta tag for CSP, update your 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