Middleware no Next.js 16 em 2026: Edge Runtime, Autenticação e Perguntas de Entrevista
Domine o middleware do Next.js 16 com Edge Runtime, padrões de autenticação e perguntas técnicas de entrevista para desenvolvedores frontend.

O middleware do Next.js 16 é executado antes de cada requisição, tornando-se a primeira linha de defesa para autenticação, localização e manipulação de requisições. Compreender o funcionamento do middleware é essencial para construir aplicações de produção e constitui um tema frequente em entrevistas técnicas de frontend.
O middleware do Next.js 16 é executado no Edge Runtime por padrão, o que significa que funciona em data centers próximos aos usuários com cold starts inferiores a um milissegundo. Isso o torna ideal para verificações de autenticação e redirecionamentos que precisam ocorrer antes da página ser renderizada.
Como o Middleware do Next.js 16 Funciona Internamente
O middleware no Next.js 16 intercepta as requisições antes que elas cheguem ao handler de rota ou ao componente de página. O arquivo de middleware deve ser colocado na raiz do projeto (ao lado de app/ ou pages/) e exporta uma função padrão que recebe um objeto NextRequest.
A restrição do Edge Runtime significa que o middleware não pode utilizar APIs do Node.js como fs ou Buffer. Ele executa em isolates V8, similar ao Cloudflare Workers, o que permite distribuição global mas limita as APIs disponíveis aos padrões Web.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Acesso aos headers, cookies e URL da requisição
const token = request.cookies.get('session')?.value
const pathname = request.nextUrl.pathname
// Log para debugging (visível nos logs da Vercel)
console.log(`Middleware: ${request.method} ${pathname}`)
// Continua para o handler de rota
return NextResponse.next()
}
// Configura quais caminhos acionam o middleware
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}A configuração matcher utiliza uma sintaxe similar a regex para definir quais caminhos acionam o middleware. Sem essa configuração, o middleware executa em cada requisição, incluindo assets estáticos.
Padrões de Autenticação com Middleware do Next.js
O middleware se destaca na proteção de rotas que requerem autenticação. Em vez de verificar a autenticação em cada componente de página, uma verificação centralizada no middleware garante que nenhuma rota protegida possa ser acessada sem uma sessão válida.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const protectedRoutes = ['/dashboard', '/settings', '/profile']
const authRoutes = ['/login', '/register']
export function middleware(request: NextRequest) {
const token = request.cookies.get('session')?.value
const pathname = request.nextUrl.pathname
// Verifica se a rota requer autenticação
const isProtectedRoute = protectedRoutes.some(route =>
pathname.startsWith(route)
)
const isAuthRoute = authRoutes.some(route =>
pathname.startsWith(route)
)
// Redireciona usuários não autenticados para a página de login
if (isProtectedRoute && !token) {
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('callbackUrl', pathname)
return NextResponse.redirect(loginUrl)
}
// Redireciona usuários autenticados para fora das páginas de auth
if (isAuthRoute && token) {
return NextResponse.redirect(new URL('/dashboard', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}Esse padrão lida tanto com a proteção de rotas quanto com a prevenção de acesso às páginas de login para usuários já autenticados.
Validação JWT no Middleware Edge
Validar tokens JWT no edge requer bibliotecas compatíveis com Edge Runtime. O pacote jose é a escolha padrão porque utiliza as APIs Web Crypto disponíveis no ambiente Edge.
import { jwtVerify } from 'jose'
const JWT_SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || 'your-secret-key'
)
export async function verifyToken(token: string) {
try {
const { payload } = await jwtVerify(token, JWT_SECRET)
return { valid: true, payload }
} catch (error) {
return { valid: false, payload: null }
}
}import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { verifyToken } from './lib/auth-edge'
export async function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
const { valid, payload } = await verifyToken(token)
if (!valid) {
// Remove o cookie inválido e redireciona
const response = NextResponse.redirect(new URL('/login', request.url))
response.cookies.delete('auth-token')
return response
}
// Adiciona informações do usuário aos headers para Server Components
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-user-id', payload?.sub as string)
requestHeaders.set('x-user-role', payload?.role as string)
return NextResponse.next({
request: { headers: requestHeaders },
})
}Passar informações do usuário através de headers permite que Server Components acessem dados de autenticação sem consultas adicionais ao banco de dados.
Gerenciamento de Internacionalização no Middleware
O middleware é o local ideal para lidar com detecção de idioma e redirecionamentos. O Next.js 16 fornece helpers integrados para internacionalização que funcionam no Edge Runtime.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
const locales = ['en', 'fr', 'de', 'es', 'ja']
const defaultLocale = 'en'
function getLocale(request: NextRequest): string {
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => {
negotiatorHeaders[key] = value
})
const languages = new Negotiator({ headers: negotiatorHeaders }).languages()
return match(languages, locales, defaultLocale)
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
// Verifica se o pathname já tem um locale
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
)
if (pathnameHasLocale) return NextResponse.next()
// Redireciona para o pathname com locale
const locale = getLocale(request)
const newUrl = new URL(`/${locale}${pathname}`, request.url)
return NextResponse.redirect(newUrl)
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}Rate Limiting no Edge
Implementar rate limiting no middleware protege as APIs contra abusos. Contadores em memória não funcionam de forma confiável no edge devido à natureza distribuída, mas soluções externas como Upstash Redis fornecem armazenamento compatível com Edge.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'
const redis = new Redis({
url: process.env.UPSTASH_REDIS_URL!,
token: process.env.UPSTASH_REDIS_TOKEN!,
})
const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(10, '10 s'),
analytics: true,
})
export async function middleware(request: NextRequest) {
// Limita apenas rotas de API
if (!request.nextUrl.pathname.startsWith('/api')) {
return NextResponse.next()
}
const ip = request.ip ?? '127.0.0.1'
const { success, limit, reset, remaining } = await ratelimit.limit(ip)
if (!success) {
return NextResponse.json(
{ error: 'Too many requests' },
{
status: 429,
headers: {
'X-RateLimit-Limit': limit.toString(),
'X-RateLimit-Remaining': remaining.toString(),
'X-RateLimit-Reset': reset.toString(),
},
}
)
}
return NextResponse.next()
}Modificação de Headers de Resposta
O middleware pode modificar headers de resposta para políticas de segurança, cache e headers personalizados. Isso ocorre após o processamento da rota, mas antes de enviar a resposta ao cliente.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const response = NextResponse.next()
// Headers de segurança
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
response.headers.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline'"
)
// Headers personalizados para debugging
response.headers.set('X-Middleware-Timestamp', Date.now().toString())
return response
}Tratamento de Erros no Middleware
O middleware deve tratar erros de forma elegante para evitar bloquear requisições. Erros não capturados no middleware resultam em uma resposta 500, o que pode bloquear o acesso a toda a aplicação.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
try {
// Operações do middleware que podem falhar
const token = request.cookies.get('session')?.value
if (token) {
const isValid = await validateSession(token)
if (!isValid) {
return NextResponse.redirect(new URL('/login', request.url))
}
}
return NextResponse.next()
} catch (error) {
// Registra o erro mas não bloqueia a requisição
console.error('Middleware error:', error)
// Opções: continuar, redirecionar para erro, ou retornar resposta de erro
return NextResponse.next()
}
}
async function validateSession(token: string): Promise<boolean> {
// Lógica de validação
return true
}Pronto para mandar bem nas entrevistas de React / Next.js?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Perguntas de Entrevista: Middleware do Next.js
As perguntas de entrevista sobre middleware avaliam a compreensão do seu modelo de execução, limitações e casos de uso apropriados.
Pergunta: Qual é a diferença entre middleware e API Routes para autenticação?
O middleware executa antes dos handlers de rota e pode interceptar requisições para qualquer rota, incluindo páginas estáticas e assets. API Routes executam apenas para requisições a /api/*. O middleware é ideal para verificações de autenticação em toda a aplicação, enquanto API Routes lidam com lógica de negócios específica.
Pergunta: Por que não é possível usar APIs do Node.js no middleware?
O middleware executa no Edge Runtime, que utiliza isolates V8 em vez de um ambiente Node.js completo. Isso permite cold starts inferiores a um milissegundo e distribuição global, mas limita as APIs disponíveis aos padrões Web (fetch, crypto, etc.).
Pergunta: Como passar dados do middleware para Server Components?
Definindo headers personalizados na requisição usando NextResponse.next({ request: { headers: modifiedHeaders } }). Server Components podem então ler esses headers usando a função headers() de next/headers.
Pergunta: Qual é a abordagem correta para gerenciamento de sessão no middleware?
Ler cookies de sessão e validar tokens usando bibliotecas compatíveis com Edge como jose para JWT. Não realizar consultas ao banco de dados diretamente no middleware; em vez disso, usar validação de tokens ou APIs de sessão externas.
Pergunta: Como implementar uma cadeia de middlewares no Next.js?
O Next.js suporta apenas um único arquivo de middleware, mas é possível encadear múltiplas funções compondo-as:
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
type MiddlewareFunction = (
request: NextRequest
) => Promise<NextResponse | null>
const withAuth: MiddlewareFunction = async (request) => {
const token = request.cookies.get('session')?.value
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url))
}
return null
}
const withLogging: MiddlewareFunction = async (request) => {
console.log(`${request.method} ${request.nextUrl.pathname}`)
return null
}
const middlewares = [withLogging, withAuth]
export async function middleware(request: NextRequest) {
for (const mw of middlewares) {
const result = await mw(request)
if (result) return result
}
return NextResponse.next()
}Melhores Práticas para Middleware em Produção
Minimizar o trabalho realizado no middleware melhora os tempos de resposta. Cada milissegundo no middleware atrasa a renderização da página. Evitar chamadas a APIs externas a menos que seja absolutamente necessário.
Usar o matcher apropriadamente reduz execuções desnecessárias do middleware. Excluir arquivos estáticos, imagens e rotas de API que não requerem processamento de middleware.
export const config = {
matcher: [
// Corresponde a todos os caminhos exceto arquivos estáticos
'/((?!_next/static|_next/image|favicon.ico|public/).*)',
// Ou lista explícita de rotas
'/dashboard/:path*',
'/api/protected/:path*',
],
}Logs no middleware devem ser mínimos em produção. Cada console.log adiciona latência e consome recursos.
Conclusão
O middleware do Next.js 16 fornece uma poderosa capacidade de interceptação de requisições que executa no edge com latência mínima. Compreender suas restrições (Edge Runtime, sem APIs do Node.js) e seus casos de uso apropriados (autenticação, i18n, rate limiting) é essencial para construir aplicações de alto desempenho. Candidatos devem ser capazes de explicar a diferença entre middleware e API Routes, demonstrar tratamento de erros apropriado e compreender como passar dados para Server Components.
Você saberia encontrar o bug em React / Next.js?
Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Escrito por
Anthony Fillion-MailletFundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 20 de setembro de 2026
Tags
Compartilhar
Artigos relacionados

Perguntas de entrevista sobre Zustand 2026: Gerenciamento de estado React e melhores práticas
Prepare suas entrevistas técnicas com este guia completo sobre Zustand. Descubra perguntas frequentes, padrões de middleware, comparação com Context API e melhores práticas TypeScript.

React 19 Suspense e Renderização Concorrente: Streaming SSR e Perguntas de Entrevista 2026
Guia completo sobre React 19 Suspense, renderização concorrente e Streaming SSR. Padrões avançados e preparação para entrevistas técnicas em 2026.

Testes em React 2026: Vitest, React Testing Library e Melhores Práticas
Dominar os testes em React com Vitest e React Testing Library. Aprender padrões de teste de componentes, tratamento assíncrono, estratégias de mocking e melhores práticas para entrevistas técnicas em 2026.