Content Security Policy (CSP) Configuration
Overview
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.
Required CSP Directives
TinaCMS requires the following CSP directives to function properly:
Image Sources
TinaCMS needs access to load images from its asset delivery network:
"img-src 'self' data: assets.tina.io;"
Connect Sources
TinaCMS requires connections to several services for authentication and content delivery:
"connect-src 'self' identity.tinajs.io content.tinajs.io assets.tinajs.io;"
- identity.tinajs.io - Authentication and identity services
- content.tinajs.io - Content API and data layer
- assets.tinajs.io - Asset management and delivery
Implementation Examples
Next.js Configuration
App Router (Next.js 13+)
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;
Pages Router
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;}
Netlify Configuration
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';"
Vercel Configuration
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';"}]}]}
Apache Configuration
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>
Nginx Configuration
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;
Self-Hosted Considerations
If you're using a self-hosted TinaCMS setup, you may need to adjust these CSP directives:
- Replace TinaCloud domains with your own backend URLs
- Ensure
connect-srcincludes your content API endpoint - Add any custom media storage domains to
img-src
Example 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];
Troubleshooting
CSP Violations in Browser Console
If you see CSP violation errors in your browser console:
- Check the error message to identify the blocked resource
- Add the appropriate domain to the relevant CSP directive
- Test thoroughly to ensure TinaCMS functionality works
Common violations:
- Blocked image loads: Add the domain to
img-src - Blocked API calls: Add the domain to
connect-src - Blocked inline styles: You may need
style-src 'unsafe-inline'for certain TinaCMS features
TinaCMS Editor Not Loading
If the TinaCMS editor fails to load:
- Verify all required domains are included in
connect-src - Check for CSP violations in the browser console
- Ensure
frame-srcallows the TinaCMS admin interface if using iframe mode
Having issues when authenticating with GitHub? It could be your CSP configuration!
Check out this GitHub issue on how it was resolved.
Testing CSP Configuration
Use browser developer tools to verify your CSP configuration:
- Open DevTools → Console
- Look for CSP violation warnings
- Click on violations to see which resources are blocked
- Update your CSP accordingly
You can also use online tools like CSP Evaluator to validate your policy.
Additional Resources
Best Practices
- Start restrictive, then loosen: Begin with a strict CSP and only add exceptions as needed
- Use report-only mode: Test CSP changes with
Content-Security-Policy-Report-Onlybefore enforcing - Regular audits: Review and update your CSP as your application evolves
- Document exceptions: Keep notes on why specific domains are whitelisted
- Environment-specific policies: Consider different CSP rules for development vs. production