middleware
O Nuxt fornece middleware para executar código antes de navegar para uma rota específica.
O Nuxt fornece um framework de middleware de rota personalizável que você pode usar em toda a sua aplicação, ideal para extrair código que você deseja executar antes de navegar para uma rota específica.
Existem três tipos de middleware de rota:
- Middleware de rota anônima (ou inline) são definidos diretamente dentro da página.
- Middleware de rota nomeada, colocados no diretório
middleware/
e carregados automaticamente via importação assíncrona quando usados em uma página. - Middleware de rota global, colocados no diretório
middleware/
com um sufixo.global
e executados em cada mudança de rota.
Os dois primeiros tipos de middleware de rota podem ser definidos em definePageMeta
.
Os nomes dos middleware são normalizados para kebab-case: myMiddleware
se torna my-middleware
.
Os middleware de rota são executados na parte Vue do seu aplicativo Nuxt. Apesar do nome semelhante, eles são completamente diferentes dos middleware de servidor, que são executados na parte do servidor Nitro do seu aplicativo.
Uso
Os middleware de rota são guardiões de navegação que recebem a rota atual e a próxima rota como argumentos.
export default defineNuxtRouteMiddleware((to, from) => {
if (to.params.id === '1') {
return abortNavigation()
}
// Em um aplicativo real, você provavelmente não redirecionaria todas as rotas para `/`
// no entanto, é importante verificar `to.path` antes de redirecionar ou você
// pode acabar em um loop de redirecionamento infinito
if (to.path !== '/') {
return navigateTo('/')
}
})
O Nuxt fornece dois auxiliares globalmente disponíveis que podem ser retornados diretamente do middleware.
navigateTo
- Redireciona para a rota dadaabortNavigation
- Aborta a navegação, com uma mensagem de erro opcional.
Ao contrário dos guardas de navegação do vue-router
, um terceiro argumento next()
não é passado, e o redirecionamento ou cancelamento de rota é tratado retornando um valor do middleware.
Os valores de retorno possíveis são:
- nada (um simples
return
ou nenhum retorno) - não bloqueia a navegação e passará para a próxima função de middleware, se houver, ou completará a navegação da rota return navigateTo('/')
- redireciona para o caminho dado e definirá o código de redirecionamento para302
Found se o redirecionamento ocorrer no lado do servidorreturn navigateTo('/', { redirectCode: 301 })
- redireciona para o caminho dado e definirá o código de redirecionamento para301
Moved Permanently se o redirecionamento ocorrer no lado do servidorreturn abortNavigation()
- interrompe a navegação atualreturn abortNavigation(error)
- rejeita a navegação atual com um erro
Recomendamos usar as funções auxiliares acima para realizar redirecionamentos ou parar a navegação. Outros valores de retorno possíveis descritos na documentação do vue-router podem funcionar, mas podem haver mudanças incompatíveis no futuro.
Ordem do Middleware
O middleware é executado na seguinte ordem:
- Middleware Global
- Ordem do middleware definido na página (se houver múltiplos middleware declarados com a sintaxe de array)
Por exemplo, assumindo que você tenha o seguinte middleware e componente:
-| middleware/
---| analytics.global.ts
---| setup.global.ts
---| auth.ts
definePageMeta({
middleware: [
function (to, from) {
// Middleware inline personalizado
},
'auth',
],
});
Você pode esperar que o middleware seja executado na seguinte ordem:
analytics.global.ts
setup.global.ts
- Middleware inline personalizado
auth.ts
Ordenando Middleware Global
Por padrão, o middleware global é executado em ordem alfabética com base no nome do arquivo.
No entanto, pode haver momentos em que você deseja definir uma ordem específica. Por exemplo, no último cenário, setup.global.ts
pode precisar ser executado antes de analytics.global.ts
. Nesse caso, recomendamos prefixar o middleware global com numeração 'alfabética'.
-| middleware/
---| 01.setup.global.ts
---| 02.analytics.global.ts
---| auth.ts
Caso você seja novo na numeração 'alfabética', lembre-se de que os nomes dos arquivos são ordenados como strings, não como valores numéricos. Por exemplo, 10.new.global.ts
viria antes de 2.new.global.ts
. É por isso que o exemplo prefixa números de um dígito com 0
.
Quando o Middleware é Executado
Se o seu site for renderizado no servidor ou gerado, o middleware para a página inicial será executado tanto quando a página for renderizada quanto novamente no cliente. Isso pode ser necessário se o seu middleware precisar de um ambiente de navegador, como se você tiver um site gerado, armazenar respostas em cache agressivamente ou quiser ler um valor do armazenamento local.
No entanto, se você quiser evitar esse comportamento, pode fazê-lo:
export default defineNuxtRouteMiddleware(to => {
// pular middleware no servidor
if (import.meta.server) return
// pular middleware no lado do cliente completamente
if (import.meta.client) return
// ou apenas pular middleware na carga inicial do cliente
const nuxtApp = useNuxtApp()
if (import.meta.client && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return
})
Isso é verdade mesmo se você lançar um erro no seu middleware no servidor, e uma página de erro for renderizada. O middleware ainda será executado novamente no navegador.
Renderizar uma página de erro é um carregamento de página completamente separado, o que significa que qualquer middleware registrado será executado novamente. Você pode usar useError
no middleware para verificar se um erro está sendo tratado.
Adicionando Middleware Dinamicamente
É possível adicionar middleware de rota global ou nomeado manualmente usando a função auxiliar addRouteMiddleware()
, como de dentro de um plugin.
export default defineNuxtPlugin(() => {
addRouteMiddleware('global-test', () => {
console.log('este middleware global foi adicionado em um plugin e será executado em cada mudança de rota')
}, { global: true })
addRouteMiddleware('named-test', () => {
console.log('este middleware nomeado foi adicionado em um plugin e substituiria qualquer middleware existente com o mesmo nome')
})
})
Exemplo
-| middleware/
---| auth.ts
No seu arquivo de página, você pode referenciar este middleware de rota:
definePageMeta({
middleware: ["auth"]
// ou middleware: 'auth'
})
Agora, antes que a navegação para essa página possa ser concluída, o middleware de rota auth
será executado.
Definindo Middleware no Momento da Construção
Em vez de usar definePageMeta
em cada página, você pode adicionar middleware de rota nomeado dentro do 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 (/* alguma condição */ true) {
page.meta ||= {}
// Note que isso substituirá qualquer middleware definido em `definePageMeta` na página
page.meta.middleware = ['named']
}
if (page.children) {
setMiddleware(page.children)
}
}
}
setMiddleware(pages)
}
}
})
※Esta página é uma tradução não oficial da documentação oficial do Nuxt.js.
A página correspondente na documentação oficial está aqui:
https://nuxt.com/docs/3.x/guide/directory-structure/middleware