Environment: server
Cumulative: false
Global: false
The +csp
setting allows you to add and configure the CSP nonce, see Content Security Policy (CSP).
// 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+csp
setting 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.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.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.headersResponse
instead of using the+headersResponse
setting.
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.ts
// Environment: server
import type { PageContextServer } from 'vike/types'
export async function onCreatePageContext(pageContext: PageContextServer) {
pageContext.cspNonce = 'some-random-string'
}
The
+csp
setting is merely a convenience to set thepageContext.cspNonce
value.
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.