import { NextResponse } from “next/server”;
import type { NextRequest } from “next/server”;
import { i18n } from “./i18n.config”;
import { match as matchLocale } from “@formatjs/intl-localematcher”;
import Negotiator from “negotiator”;
import {
publicRoutes,
DEFAULT_LOGIN_REDIRECT,
authRoutes,
protectedRoutes,
} from “./routes”;
import { getToken } from “next-auth/jwt”;
function getLocale(request: NextRequest): string | undefined {
const negotiatorHeaders: Record<string, string> = {};
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
// @ts-ignore locales are readonly
const locales: string = i18n.locales;
const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
const locale = matchLocale(languages, locales, i18n.defaultLocale);
return locale;
}
export async function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
const pathnameIsMissingLocale = i18n.locales.every(
(locale) =>
!pathname.startsWith(/${locale}/
) && pathname !== /${locale}
,
);
const isAuthRoute = authRoutes.includes(request.nextUrl.pathname);
const adminRoute = DEFAULT_LOGIN_REDIRECT;
const secret = process.env.NEXTAUTH_SECRET;
const protectedRoute = protectedRoutes.includes(request.nextUrl.pathname);
const session = await getToken({ req: request, secret });
if (isAuthRoute) {
if (session) {
return NextResponse.redirect(
new URL(“/admin”, request.nextUrl),
);
}
}
if (protectedRoute) {
if (!session) {
return NextResponse.redirect(new URL(“/login”, request.nextUrl));
}
}
// Redirect if there is no locale
if (pathnameIsMissingLocale) {
const locale = getLocale(request);
if (locale === i18n.defaultLocale) {
const newUrl = new URL(
`/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
request.url,
);
newUrl.search = request.nextUrl.search;
return NextResponse.rewrite(newUrl);
}
return NextResponse.redirect(
new URL(
`/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
request.url,
),
);
}
}
export const config = {
// Matcher ignoring /_next/
and /api/
matcher: [“/((?!api|_next/static|_next/image|favicon.ico).*)”],
};