Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.