CORS and Security Attributes
Background
When loading scripts from external domains, the script element's crossorigin setting determines whether the browser uses Cross-Origin Resource Sharing (CORS). For third-party scripts, this affects:
- Whether the browser sends cookies with requests
- Access to error details for debugging
- Subresource Integrity (SRI) validation
Default Behavior
Nuxt Scripts applies privacy-focused defaults to cross-origin scripts:
<script
src="https://example.com/script.js"
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
The attributes have separate effects:
crossorigin="anonymous": Prevents the script request from sending cross-origin credentials, including cookiesreferrerpolicy="no-referrer": Prevents sharing the page URL with third-party servers
Some vendor scripts require cookies or referrer information, so these defaults are not compatible with every endpoint.
Common CORS Errors
Script Fails to Load
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource
This occurs when a server doesn't return an appropriate Access-Control-Allow-Origin header but crossorigin="anonymous" is set. Some third-party scripts don't support CORS.
Script Loads but Functions Fail
The script loads but functionality is broken because it expected cookies or session data.
Error Details Hidden
window.onerror = msg => console.log(msg)
// Shows: "Script error." instead of actual error
Without crossorigin, browsers hide error details from external scripts for security.
Configuring CORS Attributes
Per-Script Configuration
Disable CORS attributes for scripts that don't support them:
useScript({
src: 'https://example.com/script.js',
crossorigin: false, // Remove crossorigin attribute
referrerpolicy: false, // Remove referrerpolicy attribute
})
Or use a different crossorigin value:
useScript({
src: 'https://example.com/script.js',
crossorigin: 'use-credentials', // Send cookies with request
})
The crossorigin and referrerpolicy fields are script input attributes, so configure them per script. They are not part of defaultScriptOptions.
Crossorigin Values
| Value | Cross-origin credentials | Error details | Use case |
|---|---|---|---|
anonymous | Not sent | Available if the server allows the origin | Privacy-focused default |
use-credentials | The browser sends them if its policy allows | Available if the server allows credentials and the requesting origin | Scripts requiring authentication |
false | Browser cookie policy determines whether to send them | Hidden | Scripts without CORS support |
Registry Scripts
Some registry definitions disable crossorigin for compatibility with their vendors:
const config = {
scriptInput: {
src: 'https://js.stripe.com/basil/stripe.js',
crossorigin: false,
referrerpolicy: false,
}
}
Scripts with crossorigin: false include:
- Stripe
- YouTube Player
- Usercentrics
- Ahrefs Web Analytics
- Google Sign-In
- Google reCAPTCHA
- Meta Pixel
- TikTok Pixel
- X (Twitter) Pixel
- Snapchat Pixel
- LinkedIn Insight Tag
- Cloudflare Web Analytics
- Lemon Squeezy
- Calendly
- Matomo Analytics
- Bing UET
If a registry script fails at the network layer, inspect these attributes alongside the response's CORS headers.
Subresource Integrity
For cross-origin resources, Subresource Integrity requires a CORS check. When using bundled scripts with SRI, Nuxt adds crossorigin="anonymous" automatically:
export default defineNuxtConfig({
scripts: {
assets: {
integrity: true, // Automatically sets crossorigin="anonymous"
}
}
})
Troubleshooting
Script Won't Load
- Check the browser console for CORS errors
- Set
crossorigin: falseto disable CORS mode - Verify the third-party server supports CORS headers
Script Loads but Broken
- The script may require cookies; try
crossorigin: 'use-credentials' - The script may need the referrer; set
referrerpolicy: false - Check if the script expects you to load it without CORS attributes
Debugging External Script Errors
To see full error messages from external scripts:
- Ensure the script has
crossorigin="anonymous" - Verify that the server returns an appropriate
Access-Control-Allow-Originheader - If the server doesn't support CORS, you won't get detailed errors
Bundling as an alternative
Bundling the script moves the initial request to your own domain, where it no longer needs cross-origin script handling.