import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; import { match as matchLocale } from "@formatjs/intl-localematcher"; import Negotiator from "negotiator"; import { locales, defaultLocale } from "@/lib/locales"; // Определяем предпочитаемую локаль браузера по заголовку Accept-Language. // Negotiator парсит заголовки запроса в список языков с весами, а matchLocale // сопоставляет этот список с нашими locales и возвращает лучшее совпадение // (либо defaultLocale, если ни один язык браузера не поддерживается). function getLocale(request: NextRequest): string { const negotiatorHeaders: Record = {}; request.headers.forEach((value, key) => (negotiatorHeaders[key] = value)); const languages = new Negotiator({ headers: negotiatorHeaders }).languages(); try { return matchLocale(languages, locales, defaultLocale); } catch (e) { return defaultLocale; } } export function proxy(request: NextRequest) { const { pathname } = request.nextUrl; // 1. Исключаем DOOM и статические файлы из обработки локалей // Добавляем проверку на /doom и /doom.html if ( pathname === "/doom" || pathname === "/doom.html" || pathname.startsWith("/games/") ) { return; // Просто выходим, позволяя Next.js обработать rewrites или public } // 2. Если путь уже содержит локаль (/en/... или /ru/...) — ничего не делаем, // маршрут и так попадёт в сегмент app/[lang]. const pathnameHasLocale = locales.some( (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`, ); if (pathnameHasLocale) return; // 3. Локали в пути нет (например, зашли на "/") — определяем язык браузера // и редиректим на префиксованный путь, например "/" -> "/en" или "/ru". const locale = getLocale(request); request.nextUrl.pathname = `/${locale}${pathname}`; return NextResponse.redirect(request.nextUrl); } export const config = { // Добавляем doom в matcher (negative lookahead), чтобы middleware даже не просыпался на этот запрос matcher: [ "/((?!_next|api|favicon.ico|logo.svg|doom|doom.html|games|.*\\..*).*)", ], };