summaryrefslogtreecommitdiff
path: root/middleware.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
commite0dfb55c5457aec489fc084c4567e791b4c65eb1 (patch)
tree68543a65d88f5afb3a0202925804103daa91bc6f /middleware.ts
3/25 까지의 대표님 작업사항
Diffstat (limited to 'middleware.ts')
-rw-r--r--middleware.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/middleware.ts b/middleware.ts
new file mode 100644
index 00000000..4237bfb4
--- /dev/null
+++ b/middleware.ts
@@ -0,0 +1,84 @@
+/** middleware.ts */
+export const runtime = 'nodejs';
+
+import { NextResponse } from 'next/server';
+import type { NextRequest } from 'next/server';
+import acceptLanguage from 'accept-language';
+
+import { fallbackLng, languages, cookieName } from '@/i18n/settings';
+
+acceptLanguage.languages(languages);
+
+export function middleware(request: NextRequest) {
+ /**
+ * 1. 쿠키에서 언어 가져오기
+ */
+ let lng = request.cookies.get(cookieName)?.value;
+
+ /**
+ * 2. 쿠키가 없다면 브라우저의 Accept-Language 헤더에서 언어를 추론
+ */
+ if (!lng) {
+ const headerLang = request.headers.get('accept-language');
+ lng = acceptLanguage.get(headerLang) || fallbackLng;
+ }
+
+ const { pathname, searchParams, origin } = request.nextUrl;
+
+ /**
+ * 3. "/"" 경로로 들어온 경우 -> "/{lng}"로 리다이렉트
+ * (예) / -> /en, / -> /ko ...
+ */
+ if (pathname === '/') {
+ const redirectUrl = new URL(`/${lng}`, origin);
+ // 쿼리 파라미터가 있을 경우도 붙여주기
+ redirectUrl.search = searchParams.toString();
+ return NextResponse.redirect(redirectUrl);
+ }
+
+ /**
+ * 4. 현재 pathname이 언어 경로를 포함하고 있는지 확인
+ * - /en
+ * - /en/... (다른 하위 경로들)
+ * - /ko
+ * - /ko/...
+ */
+ const hasValidLngInPath = languages.some(
+ (language) => pathname === `/${language}` || pathname.startsWith(`/${language}/`),
+ );
+
+ /**
+ * 5. 언어 경로가 누락된 경우 -> "/{lng}" + 기존 pathname 으로 리다이렉트
+ * 예) /dashboard -> /en/dashboard
+ */
+ if (!hasValidLngInPath) {
+ const redirectUrl = new URL(`/${lng}${pathname}`, origin);
+ redirectUrl.search = searchParams.toString();
+ return NextResponse.redirect(redirectUrl);
+ }
+
+ /**
+ * 6. 위 조건에 걸리지 않았다면 그대로 Next.js로 넘긴다.
+ */
+ const response = NextResponse.next();
+
+ /**
+ * 7. 쿠키에 저장된 언어와 현재 lng가 다르면 업데이트
+ */
+ const currentCookie = request.cookies.get(cookieName)?.value;
+ if (lng && lng !== currentCookie) {
+ response.cookies.set(cookieName, lng, { path: '/' });
+ }
+
+ return response;
+}
+
+/**
+ * 8. (선택) 매칭할 경로 설정
+ * - _next, 정적파일(.*), API 등의 경로는 제외시키는 예시
+ */
+export const config = {
+ matcher: [
+ '/((?!_next|.*\\..*|api).*)',
+ ],
+}; \ No newline at end of file