The CSP Challenge
By default, the@routes Blade directive outputs an inline <script> tag:
script-src 'self'), this script will be blocked and your routes won’t be available.
Solution 1: Using Nonces
The most common solution is to use a nonce (number used once) to whitelist specific inline scripts.Generating a Nonce
First, generate a cryptographically secure nonce for each request. You can do this in middleware:app/Http/Middleware/AddCspNonce.php
app/Http/Kernel.php
Using the Nonce with @routes
Pass the nonce to the@routes directive:
Using Named Parameters
You can combine the nonce with other parameters:Solution 2: JSON Mode
Alternatively, you can configure Ziggy to output routes as JSON data instead of executable JavaScript:type="application/json" are treated as data by the browser and are not executed, so they’re not blocked by CSP.
Loading the route() Function Separately
Install Ziggy’s NPM package:route() function in your JavaScript:
app.js
route() function will automatically read the Ziggy config from the JSON script tag.
Serving route() from Your Domain
If you don’t want to use NPM, you can serve Ziggy’s JavaScript file from your own domain:<script src>, it complies with script-src 'self'.
Solution 3: Using ziggy:generate
For the best CSP compatibility, generate Ziggy’s config as a separate JavaScript file:app.js
- ✅ Works with strict CSP (
script-src 'self') - ✅ No nonces required
- ✅ No inline scripts
- ✅ Can be cached by the browser
- ✅ Works with JavaScript build tools
CSP Configuration Examples
Strict CSP with Nonces
Strict CSP with JSON Mode
Strict CSP with ziggy:generate
Helper Function for Nonces
Create a global helper for accessing the CSP nonce:app/helpers.php
Laravel Packages for CSP
Several Laravel packages can help manage Content Security Policy:Spatie’s Laravel CSP
spatie/laravel-csp provides a fluent API for managing CSP headers:config/csp.php
Bepsvpt’s Secure Headers
bepsvpt/secure-headers provides comprehensive security headers including CSP:Testing CSP Configuration
Test your CSP configuration by checking the browser console for errors:CSP in Development
During development, you might want to use a more permissive CSP:Choosing the Right Approach
Nonces
Best for: Traditional Laravel apps with server-rendered Blade templatesPros:
- Simple to implement
- No build tools required
- Works with all CSP configurations
- Requires middleware
- Nonce must be regenerated per request
- Can’t cache pages with nonces
JSON Mode
Best for: Apps that want inline config but need strict CSPPros:
- No nonces required
- Config can be cached
- Works with strict CSP
- Requires loading route() separately
- Still has inline content (as JSON)
- Requires NPM or manual script hosting
ziggy:generate
Best for: SPAs and apps using JavaScript build toolsPros:
- Strictest CSP support
- Fully cacheable
- No inline content
- Works great with build tools
- Requires regenerating on route changes
- More complex setup
- Requires build tools
Can I use nonces with JSON mode?
Can I use nonces with JSON mode?
You can pass a nonce to However, since JSON script tags (
@routes when using JSON mode:type="application/json") are not executed, the nonce is not necessary and will be ignored by browsers. JSON mode is inherently CSP-safe without nonces.What about hash-based CSP?
What about hash-based CSP?
Instead of nonces, CSP supports hash-based whitelisting where you specify the hash of allowed inline scripts:This is problematic with Ziggy because:
- The Ziggy output changes when routes change
- The hash would need to be recalculated on every deployment
- You’d need to generate and store the hash somewhere
How do I handle multiple @routes calls with nonces?
How do I handle multiple @routes calls with nonces?
If you use Each script tag will include the nonce attribute and be allowed by your CSP policy.
@routes multiple times on the same page, each call generates a separate <script> tag. You need to use the same nonce for all of them:Next Steps
Blade Directive
Learn more about @routes directive options
Generating Config
Use ziggy:generate for the strictest CSP support