Faça sua pergunta e obtenha um resumo do documento referenciando esta página e o provedor AI de sua escolha
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsSe você tiver uma ideia para melhorar esta documentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.
Link do GitHub para a documentaçãoCopiar o Markdown do documento para a área de transferência
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
Middleware lhe permite interceptar requisições e respostas e injetar comportamentos dinamicamente toda vez que uma página ou endpoint for ser renderizado.
Isso também permite definir e compartilhar informações específicas da requisição entre endpoints e páginas alterando o objeto locals que é disponibilizado em todos os componentes Astro e endpoints de API.
Middleware está disponível tanto para projetos Astro SSG quanto SSR.
Uso Básico
-
Crie um arquivo src/middleware.js|ts (Como alternativa, você pode criar src/middleware/index.js|ts.)
-
Dentro deste arquivo, exporte uma função onRequest() que pode receber um object context e uma função next(). Esse não pode ser a exportação padrão (export default).
jsCopiar códigoCopiar o código para a área de transferência
export function onRequest ({ locals, request }, next) { // intercepta dados de uma requisição // opcionalmente, modifica as propriedades em `locals` locals.titulo = "Novo Título"; // retorna uma `Response` ou o resultado de chamar `next()` return next();};
-
Dentro de qualquer arquivo .astro, acesse os dados da resposta utilizando Astro.locals.
astroCopiar códigoCopiar o código para a área de transferência
---const dados = Astro.locals;---<h1>{dados.titulo}</h1><p>Essa {dados.propriedade} veio do middleware.</p>
O object context
O objeto context inclui informações que serão disponibilizadas para outros middlewares, rotas de API e rotas .astro durante o processo de renderização.
Esse é um argumento opcional passado para onRequest() que pode contar o objecto locals assim como propriedades adicionais a serem compartilhadas durante a renderização. Por exemplo, o objecto context pode incluir cookies utilizados para autenticação.
Armazenando informações em context.locals
context.locals é um objeto que pode ser manipulado dentro do middleware.
Esse objeto locals é encaminhado através do processamento da chamada e é disponibilizado como uma propriedade em APIContext e AstroGlobal. Isso permite que dados sejam compartilhados entre middlewares, rotas de API, e páginas .astro. Isso é útil para armazenar dados específicos de uma chamada, como dados do usuário, entre processos de renderização.
:::tip[Propriedades de integrações] Integrações pode definir propriedades e prover funcionalidades através do objeto locals. Se você estiver utilizando uma integração, confira a documentação para garantir que você não está sobrescrevendo uma de suas propriedades or fazendo algum trabalho desnecessário. :::
Você pode armazenar dados de qualquer tipo dentro de locals: strings, numbers, e até mesmo tipos complexos como funções e maps.
Copiar o código para a área de transferência
export function onRequest ({ locals, request }, next) { // intercepta dados de uma requisição // opcionalmente, modifica as propriedades em `locals` locals.usuario.nome = "John Wick"; locals.tituloBoasVindas = () => { return "Bem-vindo de volta, " + locals.usuario.nome; }; // retorna uma `Response` ou o resultado de chamar `next()` return next();};
Desta forma você pode utilizar essas informações dentro de qualquer arquivo .astro com Astro.locals.
Copiar o código para a área de transferência
---const titulo = Astro.locals.tituloBoasVindas();const compras = Array.from(Astro.locals.compras.entries());---<h1>{titulo}</h1><p>Essa {data.propriedade} veio do middleware.</p><ul> {compras.map(compra => { return <li>{/* faça algo com cada compra */}</li>; })}</ul>
locals é um objeto que vive e morre dentro de uma única rota AStro; quando a página de sua rota for renderizada, locals não existirá mais e um novo será criado. Informação que precise persistir entre chamadas para múltiplas páginas devem ser armazenas em outro lugar.
:::note O valor de locals não pode ser sobrescrito em tempo de execução. Fazer isso arriscaria apagar todas as informações armazenadas pelo usuário. Em modo dev, Astro valida e emite um erro se locals for sobrescrito. :::
Exemplo: editando informações sensíveis
O exemplo abaixo utiliza middleware para substituir "INFORMAÇÃO PESSOAL" pela palavra "REMOVIDO" para lhe permitir renderizar HTML modificado na sua página:
Copiar o código para a área de transferência
export const onRequest = async (context, next) => { const resposta = await next(); const html = await response.text(); const htmlDaResposta = html.replaceAll("INFORMAÇÃO PESSOAL", "REMOVIDO"); return new Response(redactedHtml, { status: 200, headers: response.headers });};
Tipos do Middleware
Você pode importar e utilizar a função utilitária defineMiddleware() para se aproveitar da segurança de tipo:
Copiar o código para a área de transferência
// src/middleware.tsimport { defineMiddleware } from "astro:middleware";// `context` e `next` são tipados automaticamenteexport const onRequest = defineMiddleware((context, next) => {});
De outra forma, se você estiver utilizando JsDoc para se aproveitar da segurança de tipo, você pode utilizar MiddlewareRequestHandler:
Copiar o código para a área de transferência
// src/middleware.js/** * @type {import("astro").MiddlewareResponseHandler} */// `context` e `next` são tipados automaticamenteexport const onRequest = (context, next) => {};
Para tipar a informação dentro de Astro.locals, o que lhe fornece preenchimento automático dentro de arquivos .astro e do código do middleware, declare um namespace global no arquivo env.d.ts:
Copiar o código para a área de transferência
/// <reference types="astro/client" />declare namespace App { interface Locals { usuario: { nome: string }, tituloBoasVindas: () => string, compras: Map<string, object> }}
Então, dentro do arquivo do middleware, podemos nos aproveitar de preenchimento automático e segurança de tipos.
Encadeando middleware
Múltiplos middlewares podem ser conectados em uma sequência ordenada utilizando sequence():
Copiar o código para a área de transferência
import { sequence } from "astro:middleware";async function validacao(_, next) { console.log("validação da requisição"); const resposta = await next(); console.log("validação da resposta"); return resposta;}async function auth(_, next) { console.log("autenticação da requisição"); const resposta = await next(); console.log("autenticação da resposta"); return resposta;}async function cumprimentos(_, next) { console.log("cumprimentos da requisição"); const resposta = await next(); console.log("comprimentos da resposta"); return resposta;}export const onRequest = sequence(validacao, auth, cumprimentos);
O exemplo acima resultará na seguinte ordem no terminal:
Copiar o código para a área de transferência
validação da requisiçãoautenticação da requisiçãocumprimentos da requisiçãocumprimentos da respostaautenticação da respostavalidação da resposta