nuxt logo

Tradução da Documentação (Não Oficial)

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:

  1. Middleware de rota anônima (ou inline) são definidos diretamente dentro da página.
  2. Middleware de rota nomeada, colocados no diretório middleware/ e carregados automaticamente via importação assíncrona quando usados em uma página.
  3. 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.

middleware/my-middleware.ts
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.

  1. navigateTo - Redireciona para a rota dada
  2. abortNavigation - 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 para 302 Found se o redirecionamento ocorrer no lado do servidor
  • return navigateTo('/', { redirectCode: 301 }) - redireciona para o caminho dado e definirá o código de redirecionamento para 301 Moved Permanently se o redirecionamento ocorrer no lado do servidor
  • return abortNavigation() - interrompe a navegação atual
  • return abortNavigation(error) - rejeita a navegação atual com um erro
Veja também api > utils > navigate-to Veja também api > utils > abort-navigation

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:

  1. Middleware Global
  2. 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/ directory
-| middleware/
---| analytics.global.ts
---| setup.global.ts
---| auth.ts
pages/profile.vue
definePageMeta({
  middleware: [
    function (to, from) {
      // Middleware inline personalizado
    },
    'auth',
  ],
});

Você pode esperar que o middleware seja executado na seguinte ordem:

  1. analytics.global.ts
  2. setup.global.ts
  3. Middleware inline personalizado
  4. 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'.

Estrutura do Diretório
-| 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:

middleware/example.ts
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

Estrutura do Diretório
-| 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.

Editar e visualizar o código de exemploexamples > routing > middleware

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.

nuxt.config.ts
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)
    }
  }
})