Middleware
Middleware (промежуточный обработчик) — функция, через которую проходит каждый запрос до того, как Astro отрисует страницу. В ней удобно делать общую для всех страниц работу: узнать посетителя по cookie, закрыть раздел от гостей, добавить заголовок к ответу.
Первый middleware
Создайте файл src/middleware.ts — имя и место фиксированы:
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => {
console.log('Запрос:', context.url.pathname);
return next();
});Обновите любую страницу — в терминале, где запущен npm run dev, появится строка вроде Запрос: /posts. Функция next() передаёт запрос дальше, к странице, и возвращает её ответ.
Данные для страниц
Объект context.locals доступен и в middleware, и в страницах как Astro.locals. Узнаем имя посетителя по cookie:
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => {
context.locals.userName = context.cookies.get('user')?.value ?? null;
return next();
});Чтобы TypeScript знал о новом поле, опишите его в src/env.d.ts:
// src/env.d.ts
declare namespace App {
interface Locals {
userName: string | null;
}
}Теперь в любой странице, которая формируется по запросу, можно написать const { userName } = Astro.locals; и вывести приветствие «Привет, Анна!».
Закрытый раздел
Middleware может не пускать к странице и вернуть свой ответ:
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => {
if (context.url.pathname.startsWith('/admin') && !context.cookies.has('user')) {
return context.redirect('/login');
}
return next();
});Гость, открывший /admin, окажется на /login. Вызов next() для него не происходит, и страница не отрисовывается.
Несколько функций
Если обработчиков несколько, их объединяют функцией sequence() из того же модуля: export const onRequest = sequence(logger, auth);. Они выполнятся по порядку.
Когда middleware срабатывает
| Страница | Когда выполняется middleware |
|---|---|
| Собирается заранее | Один раз, при сборке |
| Формируется по запросу | При каждом запросе |
Частая ошибка
Проверяют cookie в middleware для статической страницы и удивляются, что защита не работает. Для заранее собранной страницы middleware выполнился при сборке, когда посетителя ещё не было. Страницы, где важен посетитель, помечайте export const prerender = false.