-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.ts
More file actions
110 lines (84 loc) · 3.03 KB
/
middleware.ts
File metadata and controls
110 lines (84 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { NextResponse, type NextRequest } from "next/server";
import {
DEFAULT_V2_LOCALE,
LOCALE_COOKIE_NAME,
getSegmentFromLocale,
isLocaleSegment,
resolveLocale,
resolveLocaleFromAcceptLanguage,
type V2Locale,
} from "./src/i18n/routing";
const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
function withLocaleCookie(response: NextResponse, locale: V2Locale) {
response.cookies.set({
name: LOCALE_COOKIE_NAME,
value: locale,
maxAge: ONE_YEAR_IN_SECONDS,
path: "/",
sameSite: "lax",
});
return response;
}
function redirectWithLocale(request: NextRequest, pathname: string, locale: V2Locale) {
const url = request.nextUrl.clone();
url.pathname = pathname;
return withLocaleCookie(NextResponse.redirect(url), locale);
}
function continueWithLocale(locale: V2Locale) {
return withLocaleCookie(NextResponse.next(), locale);
}
function getPreferredLocale(request: NextRequest): V2Locale {
const cookieLocale = resolveLocale(request.cookies.get(LOCALE_COOKIE_NAME)?.value);
if (cookieLocale) return cookieLocale;
return resolveLocaleFromAcceptLanguage(request.headers.get("accept-language"));
}
export default function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const segments = pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
const secondSegment = segments[1];
if (pathname.startsWith("/legacy")) {
return NextResponse.next();
}
if (firstSegment) {
const resolvedFromSegment = resolveLocale(firstSegment);
if (resolvedFromSegment && segments.length === 1) {
const canonicalSegment = getSegmentFromLocale(resolvedFromSegment);
return redirectWithLocale(request, `/${canonicalSegment}/v2`, resolvedFromSegment);
}
if (resolvedFromSegment && secondSegment === "v2") {
const canonicalSegment = getSegmentFromLocale(resolvedFromSegment);
if (!isLocaleSegment(firstSegment) || firstSegment !== canonicalSegment) {
const restPath = segments.slice(1).join("/");
return redirectWithLocale(
request,
`/${canonicalSegment}/${restPath}`,
resolvedFromSegment
);
}
return continueWithLocale(resolvedFromSegment);
}
}
const isRoot = pathname === "/";
const isUnprefixedV2 = firstSegment === "v2";
if (!isRoot && !isUnprefixedV2) {
return NextResponse.next();
}
const preferredLocale = getPreferredLocale(request);
if (preferredLocale === DEFAULT_V2_LOCALE) {
const targetPath = isRoot ? "/v2" : pathname;
if (pathname !== targetPath) {
return redirectWithLocale(request, targetPath, preferredLocale);
}
return continueWithLocale(preferredLocale);
}
const localeSegment = getSegmentFromLocale(preferredLocale);
const targetPath = isRoot ? `/${localeSegment}/v2` : `/${localeSegment}${pathname}`;
if (pathname !== targetPath) {
return redirectWithLocale(request, targetPath, preferredLocale);
}
return continueWithLocale(preferredLocale);
}
export const config = {
matcher: ["/((?!api|_next|.*\\..*).*)"],
};