Usage
Learn how to use headers and middleware both globally and per route.
Nuxt Security by default registers a set of global Nuxt routeRules
that will make your application more secure by default. Both headers and middleware can be easily configured and even disabled when needed.
Global configuration
To override the default behavior for Nuxt Security globally, follow this pattern:
export default defineNuxtConfig({
security: {
headers: {
// certain header
xXSSProtection: '1',
},
// certain middleware
rateLimiter: {
// options
}
}
})
Per route configuration
To enable per-route configuration, use the routeRules
like following:
export default defineNuxtConfig({
routeRules: {
'/custom-route': {
headers: {
'Foo': 'Bar'
/* DO NOT DEFINE SECURITY HEADERS HERE
'Cross-Origin-Embedder-Policy': 'require-corp'
*/
}
security: {
// INSTEAD USE THE CUSTOM NUXT-SECURITY PROPERTY
headers: {
// certain header
crossOriginEmbedderPolicy: 'require-corp'
},
// certain middleware
rateLimiter: {
// options
}
}
}
}
})
routeRules
, do not use the standard headers
property to define Nuxt Security options.
Instead, make sure to use the
security
property. This is a custom NuxtSecurity addition that does not exists in core Nuxt.
If your application defines conflicting headers at both levels, the
security
property will take precedence.For more information on routeRules
please see the Nuxt documentation
Runtime hooks
If you need to change the configuration at runtime, it is possible to do it through the nuxt-security:routeRules
hook.
In order to use the runtime hooks feature, you will need to create a Nitro plugin.
In the server/plugins
directory, create a new file with the name of your choice:
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
// You can fetch configuration data asynchronously from an external source
const validDomain = await $fetch('https://some-site.com/rules')
// You can then override the security options of any route
routeRules['/some/route'] = {
headers: {
contentSecurityPolicy: {
"connect-src": ["'self'", validDomain]
},
xFrameOptions: false
},
hidePoweredBy: false
}
})
})
Headers delivered on other resources (e.g. images, js and css files, api routes etc.) are not modifiable via runtime hooks.
Configuration priority order
Nuxt-Security applies your rules in the following prority order:
- Default rules
Nuxt-Security default values. See here
- Inline module options
export default defineNuxtConfig({
modules: [
['nuxt-security', { /* Inline Options */ }]
]
})
- Global module options
export default defineNuxtConfig({
security: {
// Global Options
}
})
- Per-route options
export default defineNuxtConfig({
routeRules: {
'/some-route': {
security: {
// Per-route Options
}
}
}
})
- Runtime-hook options
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', routeRules => {
// Runtime Options
})
})
Route merging strategy (nested router)
If you define nested route rules in your routeRules
definitions, Nuxt Security will recursively merge the options to resolve the security rules of a given route:
export default defineNuxtConfig({
// Global
security: {
headers: {
crossOriginEmbedderPolicy: 'require-corp' // By default, COEP is 'require-corp'
}
}
// Per route
routeRules: {
'/some-prefix/**': {
security: {
headers: {
crossOriginEmbedderPolicy: false // COEP disabled on all routes beginning with /some-prefix/
}
}
},
'/some-prefix/some-route': {
security: {
headers: {
crossOriginEmbedderPolicy: 'credentialless' // COEP is 'credentialless' on /some-prefix/some-route
}
}
}
}
})
Inline route configuration
You can also use route roules in pages like following:
<template>
<div>Hello from page</div>
</template>
<script setup lang="ts">
defineRouteRules({
security: {
headers: {
xXSSProtection: '1'
},
rateLimiter: {
tokensPerInterval: 3,
interval: 60000,
},
}
})
</script>
nuxt.config.ts
file:experimental: {
inlineRouteRules: true
},
Disabling functionality
To disable certain middleware or headers, follow this pattern:
export default defineNuxtConfig({
// global
security: {
headers: {
// certain header
contentSecurityPolicy: false
},
// certain middleware
rateLimiter: false
},
// per route
routeRules: {
'/custom-route': {
security: {
rateLimiter: false
}
}
}
})
Modifying security options
Within your runtime hooks, you can either modify or overwrite the existing values for any security option.
Merging with replacement
One of the easiest way to merge existing rules with your own is to use defuReplaceArray
:
// You don't need to import defuReplaceArray as it is auto-imported by Nuxt Security
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
routeRules['/some/route'] = defuReplaceArray(
{
headers: {
contentSecurityPolicy: {
"script-src": ["'self'", "..."]
// The script-src directive will be replaced with "'self' ..."
}
}
},
routeRules['/some/route'] // The other existing rules for /some/route will be preserved
)
})
})
In the example above,
- All existing security options for
/some/route
will be maintained, and only thescript-src
CSP directive will be modified. - The existing content of the
script-src
directive will be erased and replaced by your values
Read more about defuReplaceArray
defuReplaceArray
is auto-imported by Nuxt Security. You can use this utility anywhere in your /server folder.Merging with addition
If you want to add additional values to the existing settings, you can use the standard defu
utility to merge your rules.
// You will need to import defu
import { defu } from 'defu'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
routeRules['/some/route'] = defu(
{
headers: {
contentSecurityPolicy: {
"script-src": ["'self'", "..."]
// The values "'self' ..." will be added to the existing values
}
}
},
routeRules['/some/route'] // The other existing rules for /some/route will be preserved
)
})
})
In the example above,
- All existing security options for
/some/route
will be maintained, and only thescript-src
CSP directive will be modified. - The existing content of the
script-src
directive will be preserved, and your values will be added to the existing values.
Read more about defu
Overwriting rules
If you want to erase the existing settings, don't use defu and overwrite the values:
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('nuxt-security:routeRules', async(routeRules) => {
routeRules['/some/route'] = {
headers: {
contentSecurityPolicy: {
"script-src": ["'self'", "..."]
}
}
}
// Any existing rules for /some/route will be erased
})
})
In the example above,
- All existing security options for
/some/route
will be erased. - The
script-src
directive will contain your values.