Back

Um Guia para Iniciantes sobre Middleware no React Router

Um Guia para Iniciantes sobre Middleware no React Router

Introdução

Se você já precisou verificar autenticação antes de cada rota protegida, registrar requisições em toda a sua aplicação ou compartilhar dados entre rotas pai e filho no React Router, provavelmente escreveu o mesmo código várias vezes. O middleware do React Router resolve esse problema de repetição permitindo que você intercepte e processe requisições antes que elas cheguem aos seus loaders e actions.

Este guia cobre tudo o que você precisa para implementar middleware no React Router versão 7.9+, desde a habilitação da flag v8_middleware até a criação do seu primeiro middleware de autenticação com a nova API de middleware.

Principais Conclusões

  • React Router 7 introduz middleware para lidar com preocupações transversais como autenticação e logging
  • Middleware executa sequencialmente em uma cadeia aninhada, permitindo compartilhamento eficiente de dados entre rotas
  • A nova API de contexto fornece compartilhamento de dados type-safe sem conflitos de nomenclatura
  • Tanto middleware de servidor quanto de cliente são suportados com diferentes comportamentos de execução

O que é Middleware do React Router?

O middleware do React Router 7 é um recurso que executa código antes e depois da execução dos seus manipuladores de rota. Pense nele como um pipeline de processamento onde cada middleware pode inspecionar requisições, adicionar dados ao contexto ou até mesmo interromper a requisição com um redirecionamento.

Diferentemente da execução paralela de loaders no React Router 6, o middleware executa sequencialmente em uma cadeia aninhada. O middleware pai executa antes do middleware filho na descida, depois em ordem reversa na subida após gerar uma resposta.

Middleware pai → Middleware filho → Manipulador de rota → Middleware filho → Middleware pai

Esta execução sequencial habilita padrões que eram anteriormente impossíveis, como compartilhar dados de usuário autenticado de uma rota pai para todas as rotas filhas sem chamadas redundantes ao banco de dados.

Habilitando Middleware no Seu Projeto

Para começar a usar middleware, primeiro certifique-se de estar executando React Router 7.9.0 ou posterior (ou 7.3.0+ com a flag de middleware habilitada). Em seguida, habilite a feature flag na sua configuração:

// react-router.config.ts
import type { Config } from "@react-router/dev/config";

export default {
  future: {
    v8_middleware: true,
  },
} satisfies Config;

Esta flag habilita o suporte estável a middleware e a nova API de contexto. O parâmetro context nos seus loaders e actions agora fornece acesso aos dados definidos pelo middleware através de uma API type-safe.

Entendendo a API de Contexto

A nova API de contexto no React Router 7 fornece uma interface semelhante a Map e type-safe para compartilhar dados entre middleware e manipuladores de rota. Em vez de anexar propriedades diretamente a um objeto de contexto, você agora usa context.set() e context.get() com chaves de contexto tipadas:

import { createContext } from "react-router";

// Cria uma chave de contexto tipada
const userContext = createContext<User>();

// No middleware
context.set(userContext, user);

// No loader/action
const user = context.get(userContext); // Objeto User type-safe

Esta abordagem elimina asserções de tipo do TypeScript e previne conflitos de nomenclatura entre diferentes middlewares.

Criando Seu Primeiro Middleware

Vamos construir um middleware de autenticação que protege rotas e compartilha dados do usuário:

// app/middleware/auth.ts
import { redirect, createContext } from "react-router";
import type { Route } from "./+types/root";

export const userContext = createContext<User | null>();

export const authMiddleware: Route.Middleware = async ({ 
  request, 
  context,
  next
}) => {
  const user = await getUserFromSession(request);
  
  if (!user) {
    throw redirect("/login");
  }
  
  context.set(userContext, user);
  return next();
};

Aplique este middleware às rotas protegidas:

// app/routes/dashboard.tsx
import { authMiddleware, userContext } from "~/middleware/auth";

export  const  middleware: Route.MiddlewareFunction[] = [authMiddleware];

export async function loader({ context }: Route.LoaderArgs) {
  const user = context.get(userContext); // Garantido existir
  const profile = await getProfile(user.id);
  return { profile };
}

O middleware executa antes do loader, garantindo acesso autenticado e fornecendo o objeto de usuário sem consultas adicionais ao banco de dados.

Middleware de Servidor vs Middleware de Cliente

React Router suporta tanto middleware de servidor quanto de cliente com comportamentos ligeiramente diferentes:

Middleware de servidor executa no servidor e deve retornar uma Response:

export const middleware: Route.MiddlewareFunction[] = [
  async ({ request }, next) => {
    console.log(`Servidor: ${request.method} ${request.url}`);
    const response = await next();
    response.headers.set("X-Custom-Header", "value");
    return response; // Obrigatório
  };
];

Middleware de cliente executa no navegador durante a navegação client-side:

export const middleware: Route.ClientMiddlewareFunction[] = [
  async ({ next }) => {
    const start = performance.now();
    await next();
    console.log(`Navegação levou ${performance.now() - start}ms`);
  },
];

Padrões Comuns de Middleware

Middleware de Logging

export const loggingMiddleware: Route.Middleware = async ({ request, next }) => {
  const requestId = crypto.randomUUID();
  console.log(`[${requestId}] ${request.method} ${request.url}`);
  
  const response = await next();
  
  console.log(`[${requestId}] Response ${response.status}`);
  return response;
};

Compondo Múltiplos Middlewares

Você pode encadear múltiplas funções de middleware juntas:

// app/routes/admin.tsx
export const middleware = [
  loggingMiddleware,
  authMiddleware,
  adminRoleMiddleware
];

Cada middleware executa em ordem, e qualquer um pode interromper a cadeia lançando um redirect ou resposta de erro.

Conclusão

O middleware do React Router transforma como você lida com preocupações transversais na sua aplicação. Ao habilitar a flag v8_middleware e adotar a nova API de contexto, você pode eliminar duplicação de código, compartilhar dados eficientemente entre rotas e implementar autenticação, logging e outros padrões de forma limpa e reutilizável.

Comece com middleware simples como autenticação ou logging, depois explore padrões avançados conforme sua aplicação cresce. O modelo de execução sequencial e a API de contexto type-safe tornam o middleware uma adição poderosa ao seu kit de ferramentas do React Router.

Perguntas Frequentes

Não, middleware é um novo recurso introduzido por trás de uma flag no React Router 7.3, estabilizado na 7.9 via `future.v8_middleware`. Versões anteriores requerem implementar funcionalidade similar através de componentes wrapper ou lógica customizada de loader.

Middleware pode melhorar o desempenho reduzindo operações redundantes. Como o middleware executa sequencialmente e pode compartilhar dados através do contexto, você evita consultas duplicadas ao banco de dados ou chamadas de API que podem ocorrer com loaders paralelos.

Quando o middleware lança um erro, o React Router o trata como qualquer outro erro de rota. O erro propaga até o error boundary mais próximo, e os middlewares subsequentes na cadeia não serão executados.

Middleware não pode modificar diretamente o objeto request, mas pode adicionar dados ao contexto que loaders e actions podem acessar. Para modificações de requisição, crie um novo objeto Request e passe-o para o próximo middleware.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay