middleware
Nuxt proporciona middleware para ejecutar código antes de navegar a una ruta particular.
Nuxt proporciona un marco de trabajo de middleware de ruta personalizable que puedes usar en toda tu aplicación, ideal para extraer código que deseas ejecutar antes de navegar a una ruta particular.
Hay tres tipos de middleware de ruta:
- Middleware de ruta anónimo (o en línea) se define directamente dentro de la página.
- Middleware de ruta nombrado, colocado en el directorio
middleware/
y cargado automáticamente mediante importación asíncrona cuando se usa en una página. - Middleware de ruta global, colocado en el directorio
middleware/
con un sufijo.global
y se ejecuta en cada cambio de ruta.
Los dos primeros tipos de middleware de ruta se pueden definir en definePageMeta
.
El nombre del middleware se normaliza a kebab-case: myMiddleware
se convierte en my-middleware
.
El middleware de ruta se ejecuta dentro de la parte Vue de tu aplicación Nuxt. A pesar del nombre similar, son completamente diferentes del middleware del servidor, que se ejecutan en la parte del servidor Nitro de tu aplicación.
Uso
El middleware de ruta son guardianes de navegación que reciben la ruta actual y la siguiente ruta como argumentos.
export default defineNuxtRouteMiddleware((to, from) => {
if (to.params.id === '1') {
return abortNavigation()
}
// En una aplicación real probablemente no redirigirías cada ruta a `/`
// sin embargo, es importante verificar `to.path` antes de redirigir o podrías
// entrar en un bucle de redirección infinito
if (to.path !== '/') {
return navigateTo('/')
}
})
Nuxt proporciona dos ayudantes disponibles globalmente que se pueden devolver directamente desde el middleware.
navigateTo
- Redirige a la ruta dadaabortNavigation
- Aborta la navegación, con un mensaje de error opcional.
A diferencia de los guardianes de navegación de vue-router
, no se pasa un tercer argumento next()
, y la redirección o cancelación de la ruta se maneja devolviendo un valor desde el middleware.
Los valores de retorno posibles son:
- nada (un simple
return
o no retornar nada) - no bloquea la navegación y pasará a la siguiente función de middleware, si la hay, o completará la navegación de la ruta return navigateTo('/')
- redirige a la ruta dada y establecerá el código de redirección a302
Found si la redirección ocurre en el lado del servidorreturn navigateTo('/', { redirectCode: 301 })
- redirige a la ruta dada y establecerá el código de redirección a301
Moved Permanently si la redirección ocurre en el lado del servidorreturn abortNavigation()
- detiene la navegación actualreturn abortNavigation(error)
- rechaza la navegación actual con un error
Recomendamos usar las funciones de ayuda mencionadas anteriormente para realizar redirecciones o detener la navegación. Otros valores de retorno posibles descritos en la documentación de vue-router pueden funcionar, pero podrían haber cambios incompatibles en el futuro.
Orden del Middleware
El middleware se ejecuta en el siguiente orden:
- Middleware Global
- Orden del middleware definido en la página (si hay múltiples middleware declarados con la sintaxis de arreglo)
Por ejemplo, suponiendo que tienes el siguiente middleware y componente:
-| middleware/
---| analytics.global.ts
---| setup.global.ts
---| auth.ts
definePageMeta({
middleware: [
function (to, from) {
// Middleware en línea personalizado
},
'auth',
],
});
Puedes esperar que el middleware se ejecute en el siguiente orden:
analytics.global.ts
setup.global.ts
- Middleware en línea personalizado
auth.ts
Ordenando el Middleware Global
Por defecto, el middleware global se ejecuta alfabéticamente basado en el nombre del archivo.
Sin embargo, puede haber ocasiones en las que desees definir un orden específico. Por ejemplo, en el último escenario, setup.global.ts
puede necesitar ejecutarse antes que analytics.global.ts
. En ese caso, recomendamos prefijar el middleware global con numeración 'alfabética'.
-| middleware/
---| 01.setup.global.ts
---| 02.analytics.global.ts
---| auth.ts
En caso de que seas nuevo en la numeración 'alfabética', recuerda que los nombres de archivo se ordenan como cadenas, no como valores numéricos. Por ejemplo, 10.new.global.ts
vendría antes que 2.new.global.ts
. Por eso el ejemplo prefija los números de un solo dígito con 0
.
Cuándo se Ejecuta el Middleware
Si tu sitio es renderizado por el servidor o generado, el middleware para la página inicial se ejecutará tanto cuando la página se renderiza como luego en el cliente. Esto podría ser necesario si tu middleware necesita un entorno de navegador, como si tienes un sitio generado, cacheas respuestas agresivamente, o deseas leer un valor del almacenamiento local.
Sin embargo, si deseas evitar este comportamiento, puedes hacerlo:
export default defineNuxtRouteMiddleware(to => {
// omitir middleware en el servidor
if (import.meta.server) return
// omitir middleware en el lado del cliente completamente
if (import.meta.client) return
// o solo omitir middleware en la carga inicial del cliente
const nuxtApp = useNuxtApp()
if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
})
Esto es cierto incluso si lanzas un error en tu middleware en el servidor, y se renderiza una página de error. El middleware aún se ejecutará nuevamente en el navegador.
Renderizar una página de error es una carga de página completamente separada, lo que significa que cualquier middleware registrado se ejecutará nuevamente. Puedes usar useError
en el middleware para verificar si se está manejando un error.
Agregar Middleware Dinámicamente
Es posible agregar middleware de ruta global o nombrado manualmente usando la función de ayuda addRouteMiddleware()
, como desde dentro de un plugin.
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-test', () => {
console.log('este middleware global fue agregado en un plugin y se ejecutará en cada cambio de ruta')
}, { global: true })
addRouteMiddleware('named-test', () => {
console.log('este middleware nombrado fue agregado en un plugin y sobrescribiría cualquier middleware existente con el mismo nombre')
})
})
Ejemplo
-| middleware/
---| auth.ts
En tu archivo de página, puedes referenciar este middleware de ruta:
definePageMeta({
middleware: ["auth"]
// o middleware: 'auth'
})
Ahora, antes de que la navegación a esa página pueda completarse, se ejecutará el middleware de ruta auth
.
Configurando Middleware en Tiempo de Construcción
En lugar de usar definePageMeta
en cada página, puedes agregar middleware de ruta nombrado dentro del hook pages:extend
.
import type { NuxtPage } from 'nuxt/schema'
export default defineNuxtConfig({
hooks: {
'pages:extend' (pages) {
function setMiddleware (pages: NuxtPage[]) {
for (const page of pages) {
if (/* alguna condición */ true) {
page.meta ||= {}
// Ten en cuenta que esto sobrescribirá cualquier middleware establecido en `definePageMeta` en la página
page.meta.middleware = ['named']
}
if (page.children) {
setMiddleware(page.children)
}
}
}
setMiddleware(pages)
}
}
})
※Esta página es una traducción no oficial de la documentación oficial de Nuxt.js.
La página correspondiente en la documentación oficial está aquí:
https://nuxt.com/docs/3.x/guide/directory-structure/middleware