+csp
{
nonce:
| boolean
| ((pageContext: PageContextServer) => string | Promise<string>)
}vikeThe +csp setting allows you to add and configure the CSP nonce, see Content Security Policy (CSP).
// pages/+config.js
export default {
csp: { nonce: true }
}// pages/+config.ts
import type { Config } from 'vike/types'
export default {
csp: { nonce: true }
} satisfies Config
If +csp.nonce is true, Vike generates a random string (the nonce value) for each HTTP request, stores it in pageContext.cspNonce, and appends it to <script> tags.
// Vike adds the nonce to each <script> it injects
<script nonce={pageContext.cspNonce}>⚠️The+cspsetting is a beta feature: expect breaking changes in any minor version update. See #2665 - Stabilize+csp.
You can generate the nonce value yourself:
// pages/+csp.js
export default {
async nonce(pageContext) {
return 'some-random-string'
}
}// pages/+csp.ts
import type { PageContextServer } from 'vike/types'
export default {
async nonce(pageContext: PageContextServer) {
return 'some-random-string'
}
}The following default CSP header is added to the HTTP response headers:
Content-Security-Policy: script-src 'self' 'nonce-${pageContext.cspNonce}'This CSP header authorizes Vike's inline scripts (without having to open the door to all inline scripts via
'unsafe-inline').
To change the CSP header you can use the +headersResponse setting:
// pages/+headersResponse.js
export function headersResponse(pageContext) {
return {
// Custom CSP header instead of Vike's default
'Content-Security-Policy': `script-src 'self' 'nonce-${pageContext.cspNonce}'; img-src 'self'`
}
}// pages/+headersResponse.ts
import type { PageContextServer } from 'vike/types'
export function headersResponse(pageContext: PageContextServer) {
return {
// Custom CSP header instead of Vike's default
'Content-Security-Policy': `script-src 'self' 'nonce-${pageContext.cspNonce}'; img-src 'self'`
}
}You can also directly modify
pageContext.headersResponseinstead of using the+headersResponsesetting.
Random string generation
If the crypto module is available, Vike uses it to generate a random string that serves as the CSP nonce:
import { randomBytes } from 'crypto'
// Generate a cryptographically secure nonce for Content Security Policy (CSP).
// Returns a base64url-encoded nonce string (URL-safe, no padding).
function generateNonce() {
return randomBytes(16).toString('base64url')
}If the crypto module isn't available (e.g. on some edge platforms), Vike falls back to:
function generateNonce() {
return Math.random().toString(36).substring(2, 18)
}pageContext.cspNonce
The nonce value is stored at pageContext.cspNonce.
You can directly set pageContext.cspNonce instead of using the +csp setting:
// pages/+onCreatePageContext.server.js
// Environment: server
export async function onCreatePageContext(pageContext) {
pageContext.cspNonce = 'some-random-string'
}// pages/+onCreatePageContext.server.ts
// Environment: server
import type { PageContextServer } from 'vike/types'
export async function onCreatePageContext(pageContext: PageContextServer) {
pageContext.cspNonce = 'some-random-string'
}The
+cspsetting is merely a convenience to set thepageContext.cspNoncevalue.
PCI
Using a CSP nonce helps maintain PCI DSS compliance. Inline scripts are allowed only if they include the generated nonce (section 6.4.3 of PCI DSS 4.0.1). Avoid using 'unsafe-inline' in the CSP header's script-src, as it would violate PCI security requirements.
<!-- ❌ Not allowed -->
<script>alert('hello')</script>
<!-- ✅ Allowed -->
<script nonce="jy8W9w1ljXuO4Xq9rft15w">alert('hello')</script>By generating a unique nonce for each request, Vike ensures that inline scripts remain secure and compliant.