> Как работают middleware в Next.js (JavaScript, Next.js)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: ДиджиталСектор, Библио-Глобус

Стек: JavaScript, Next.js

> Пример ответа

Короткий ответ

Middleware в Next.js - это функция, которая выполняется перед каждым запросом к серверу, позволяя перехватывать и модифицировать ответы на основе URL, cookies, headers или других параметров. Она работает на edge runtime, обеспечивая минимальную задержку. Middleware используется для редиректов, аутентификации, геоблокировки, A/B тестирования и логирования. Файл middleware.ts располагается в корне проекта и экспортирует функцию middleware, которая получает объект NextRequest и возвращает NextResponse.

Подробное объяснение

Middleware в Next.js - это механизм, который выполняется на уровне edge-сети (Vercel Edge Functions или собственный edge runtime) до того, как запрос достигнет страницы или API-роута. Это позволяет обрабатывать запросы с минимальной задержкой, так как код выполняется в CDN-узлах, близких к пользователю.

Основные возможности middleware:

  • Редиректы: перенаправление пользователей на другие страницы (например, при отсутствии авторизации)
  • Перезапись URL (rewrite): изменение пути запроса без изменения URL в браузере (полезно для A/B тестирования или локализации)
  • Установка headers: добавление или изменение заголовков ответа
  • Чтение cookies и headers: проверка токенов, user-agent, IP-адреса
  • Геоблокировка: ограничение доступа по стране
  • Логирование: запись метрик запросов

Middleware работает на основе паттерна "matcher", который определяет, для каких путей выполнять функцию. Это важно для производительности, так как middleware выполняется для каждого запроса, и неоптимальный matcher может замедлить все запросы.

Функция middleware принимает объект NextRequest (расширение стандартного Request) и должна возвращать NextResponse (расширение Response). Если middleware не возвращает ничего, запрос продолжается к следующему обработчику (странице или API-роуту).

Важно: middleware не может использовать Node.js API (fs, path, process.env напрямую) - только edge-совместимые модули. Это ограничение связано с выполнением на edge runtime.

На практике

В реальных проектах middleware чаще всего применяется для:

  • Аутентификации: проверка JWT-токена в cookies и редирект на страницу логина при его отсутствии
  • Локализации: определение языка пользователя по Accept-Language header или cookies и редирект на соответствующую локаль
  • Защиты API-роутов: проверка API-ключей или сессий для /api/* путей
  • A/B тестирования: случайное распределение пользователей на разные версии страниц через rewrite
  • SEO-оптимизации: установка canonical link, hreflang тегов через headers

При работе с middleware важно помнить о производительности: каждый запрос проходит через middleware, поэтому код должен быть максимально легковесным. Избегайте тяжелых вычислений, внешних API-вызовов (если они не кэшируются) и больших зависимостей.

Пример кода

TYPESCRIPT
// middleware.ts в корне проекта
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
const { pathname } = request.nextUrl;
// Пропускаем страницу логина и статические файлы
if (pathname === '/login' || pathname.startsWith('/_next/')) {
return NextResponse.next();
}
// Защита API-роутов
if (pathname.startsWith('/api/')) {
if (!token) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
return NextResponse.next();
}
// Редирект на логин для защищенных страниц
if (!token) {
const loginUrl = new URL('/login', request.url);
loginUrl.searchParams.set('redirect', pathname);
return NextResponse.redirect(loginUrl);
}
// Установка заголовка для идентификации пользователя
const response = NextResponse.next();
response.headers.set('x-user-id', token);
return response;
}
export const config = {
matcher: [
// Применять ко всем путям, кроме статики и изображений
'/((?!_next/static|_next/image|favicon.ico|.*\\.png$).*)',
],
};

Как отвечать на собеседовании

Начните с краткого определения middleware, затем перечислите основные use cases. Подчеркните, что middleware работает на edge runtime - это ключевое отличие от обычных API-роутов. Упомяните matcher и важность его настройки для производительности. Если спросят про ограничения, скажите, что middleware не имеет доступа к Node.js API и должна быть легковесной. Хорошо показать понимание разницы между redirect и rewrite. Для senior-уровня добавьте рассуждение о trade-off: middleware vs API-роуты для аутентификации, и когда лучше использовать middleware, а когда - getServerSideProps или layout.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание места middleware в жизненном цикле запроса Next.js
  • Знание edge runtime и его ограничений
  • Умение различать redirect, rewrite и next()
  • Практический опыт: типичные сценарии использования
  • Понимание производительности: как matcher влияет на скорость
  • Способность объяснить, когда middleware не подходит (например, для тяжелых вычислений)

Типичные ошибки

  • Использование Node.js API в middleware (fs, path) - это вызовет ошибку на edge runtime
  • Отсутствие matcher - middleware будет выполняться для всех запросов, включая статику, что замедляет сайт
  • Тяжелые вычисления внутри middleware - блокирует обработку запросов
  • Неправильный редирект - создание бесконечного цикла редиректов (например, редирект с /login на /login)
  • Игнорирование кэширования - middleware выполняется при каждом запросе, даже для статически сгенерированных страниц
  • Путаница между NextResponse.redirect и NextResponse.rewrite - redirect меняет URL в браузере, rewrite - нет

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью