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 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
Nested route configuration
Nuxt Security will recursively resolve nested routes using your routeRules
definitions:
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 } } }})
Runtime hooks
If you need to change the configuration at runtime, it is possible to do it through nuxt-security:routeRules
hook.
Usage
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.
You can give it any name of your choice, e.g. my-runtime-security-config.ts
:
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 } })})
Consistent with the Nuxt router rules, your new route configuration will be merged recursively with higher-level existing security route rules.
Overwriting or modifying existing values
If you don't want to overwrite existing rules with your runtime hook, you can modify existing values.
One of the easiest way to merge existing rules with your own is to use defu
:
import defu from 'defu'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'] = defu( { headers: { contentSecurityPolicy: { "connect-src": ["'self'", validDomain] }, xFrameOptions: false }, hidePoweredBy: false }, routeRules['/some/route'] ) })})