Content Security Policy (CSP) is a security standard that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks. When using TinaCMS, you'll need to configure your CSP headers to allow connections to TinaCMS services.
TinaCMS requires the following CSP directives to function properly:
TinaCMS needs access to load images from its asset delivery network:
"img-src 'self' data: assets.tina.io;"
TinaCMS requires connections to several services for authentication and content delivery:
"connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io;"
Add CSP headers in your next.config.js:
const baseCsp = ["default-src 'self';","img-src 'self' data: assets.tina.io;","font-src 'self' data: fonts.gstatic.com;","object-src 'none';","frame-src 'none';","worker-src 'self' blob:;","frame-ancestors 'none';","base-uri 'self';","connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io;"];/** @type {import('next').NextConfig} */const nextConfig = {async headers() {return [{source: '/:path*',headers: [{key: 'Content-Security-Policy',value: baseCsp.join(' '),},],},];},};module.exports = nextConfig;
For the Pages Router, you can also configure CSP in next.config.js using the same approach shown above.
Alternatively, set CSP headers in your middleware:
// middleware.tsimport { NextResponse } from 'next/server';import type { NextRequest } from 'next/server';export function middleware(request: NextRequest) {const response = NextResponse.next();const csp = ["default-src 'self'","img-src 'self' data: assets.tina.io","connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io",// ... other directives].join('; ');response.headers.set('Content-Security-Policy', csp);return response;}
Add CSP headers in your netlify.toml:
[[headers]]for = "/*"[headers.values]Content-Security-Policy = "default-src 'self'; img-src 'self' data: assets.tina.io; connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io; font-src 'self' data: fonts.gstatic.com; object-src 'none'; frame-src 'none'; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self';"
Add headers in your vercel.json:
{"headers": [{"source": "/(.*)","headers": [{"key": "Content-Security-Policy","value": "default-src 'self'; img-src 'self' data: assets.tina.io; connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io; font-src 'self' data: fonts.gstatic.com; object-src 'none'; frame-src 'none'; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self';"}]}]}
Add to your .htaccess file:
<IfModule mod_headers.c>Header set Content-Security-Policy "default-src 'self'; img-src 'self' data: assets.tina.io; connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io; font-src 'self' data: fonts.gstatic.com; object-src 'none'; frame-src 'none'; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self';"</IfModule>
Add to your nginx configuration:
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: assets.tina.io; connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io; font-src 'self' data: fonts.gstatic.com; object-src 'none'; frame-src 'none'; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self';" always;
If you're using a self-hosted TinaCMS setup, you may need to adjust these CSP directives:
connect-src includes your content API endpointimg-srcExample for self-hosted:
const baseCsp = ["default-src 'self';","img-src 'self' data: your-media-storage.example.com;","connect-src 'self' your-backend.example.com;",// ... other directives];
If you see CSP violation errors in your browser console:
Common violations:
img-srcconnect-srcstyle-src 'unsafe-inline' for certain TinaCMS featuresIf the TinaCMS editor fails to load:
connect-srcframe-src allows the TinaCMS admin interface if using iframe modeHaving issues when authenticating with GitHub? It could be your CSP configuration!
Check out this GitHub issue on how it was resolved.
Use browser developer tools to verify your CSP configuration:
You can also use online tools like CSP Evaluator to validate your policy.
Content-Security-Policy-Report-Only before enforcing