Skip to content

Conversation

@chaeyoungwon
Copy link
Contributor

@chaeyoungwon chaeyoungwon commented Jan 28, 2026

💡 PR 타입

  • 기능 추가
  • 버그 수정
  • 코드 개선
  • 문서 수정
  • 기타

📝 PR 내용

  • 404 페이지 퍼블리싱을 진행했습니다.
    /[locale] 라우트에서 발생하는 404를 처리하기 위해 app/[locale]/not-found.tsx를 추가했습니다.
    [locale]/layout.tsx에서 이미 NextIntlClientProvider를 감싸고 있어 Provider 중첩 없이 공통 404 UI 컴포넌트를 렌더링하도록 구성했고, 중복되는 UI는 공통 컴포넌트로 분리했습니다.
    또한 locale 없는 접근 시(루트 404) 대시보드 헤더 번역 이슈로 인해 app/not-found.tsx에서는 Provider로 한 번 더 감싸도록 처리했습니다.

  • 최근 사용 언어가 404에서도 유지되도록 쿠키 기반 locale 처리를 추가했습니다.
    LanguageDropdown에서 선택한 언어를 NEXT_LOCALE 쿠키로 저장하고,
    locale prefix가 없는 404 경로에서는 해당 쿠키를 기준으로 locale을 결정해 404 페이지를 렌더링합니다.

  • 유효하지 않은 경로가 locale 라우팅으로 처리되던 이슈를 수정했습니다.
    /1과 같은 잘못된 경로가 /ko/1로 리다이렉트되던 문제를 해결하기 위해 middleware 로직을 분기하여,
    실제 존재하는 페이지만 locale 라우팅을 적용하고 그 외 경로는 정상적으로 404 화면이 노출되도록 수정했습니다.

🔍 관련 이슈

📸 작업 화면

스크린샷 2026-01-28 오후 4 43 10 스크린샷 2026-01-28 오후 4 42 56

Summary by CodeRabbit

  • 새로운 기능
    • 다국어(영/한) 404 페이지 추가 — 지역화된 안내 및 홈으로 복귀 버튼 제공
  • 개선 사항
    • 언어 변경 시 선택한 로케일을 쿠키에 저장하여 유지
    • 로케일 기반 경로 처리가 개선되어 사용자가 올바른 지역화 페이지로 안내됨

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 28, 2026

설명 (Walkthrough)

프로젝트에 지역화된 404 페이지를 추가합니다. 영어/한국어 메시지를 추가하고, 서버측 및 로케일별 NotFound 라우트를 도입하며, 미들웨어와 설정에서 NEXT_LOCALE 쿠키를 이용한 로케일 라우팅/저장을 처리합니다.

변경사항 (Changes)

Cohort / File(s) 설명
지역화 메시지
messages/en.json, messages/ko.json
최상위 notFound 객체 추가: badge, title, description, homeButton 키 추가 (영/한)
루트 및 로케일 404 페이지
src/app/not-found.tsx, src/app/[locale]/not-found.tsx
서버 컴포넌트 NotFoundPage 추가: 쿠키 기반 로케일 결정, getMessages로 메시지 로드 후 NextIntlClientProvider로 래핑하여 NotFound 렌더링
공통 404 UI 컴포넌트
src/components/common/NotFound.tsx
클라이언트 컴포넌트 NotFound 추가: i18n 사용(useTranslations("notFound")), 홈 버튼으로 라우팅
설정에서 로케일 저장
src/components/mypage/SettingsContent.tsx
언어 변경 핸들러에 NEXT_LOCALE 쿠키 설정(1년) 추가 후 라우터 교체
미들웨어 / 프록시 라우팅
src/proxy.ts
localePages 목록 추가 및 로케일 인식 라우팅 재구성: 로케일 접두사 감지, 일부 페이지는 locale-agnostic 처리, 나머지는 쿠키/기본 로케일로 리라이트

시퀀스 다이어그램 (Sequence Diagram)

sequenceDiagram
    participant Client as 클라이언트
    participant Middleware as 미들웨어\n(`src/proxy.ts`)
    participant RootHandler as 루트 NotFound\n(`src/app/not-found.tsx`)
    participant Provider as NextIntlClientProvider
    participant Component as NotFound 컴포넌트

    Client->>Middleware: 존재하지 않는 경로 요청
    Middleware->>RootHandler: 라우팅/리라이트 결정 및 호출
    RootHandler->>RootHandler: cookies()에서 NEXT_LOCALE 읽기
    RootHandler->>RootHandler: 로케일 유효성 검사 / 기본값 적용
    RootHandler->>RootHandler: getMessages(선택된 로케일) 호출
    RootHandler->>Provider: 로케일 및 메시지 전달하여 래핑
    Provider->>Component: 번역 데이터 제공
    Component->>Client: 404 페이지 HTML 응답
Loading

예상 코드 리뷰 소요 시간 (Estimated code review effort)

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 'Pull request title provided by the author'과 정확히 일치하며, 404 페이지 퍼블리싱이라는 주요 변경 사항을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 PR 타입(기능 추가), PR 내용(404 페이지 퍼블리싱 상세 설명), 관련 이슈(#30), 작업 화면 스크린샷을 포함하고 있습니다.
Linked Issues check ✅ Passed PR은 #30의 '404 페이지 UI 구현' 요구사항을 충족하며, 404 페이지 UI 컴포넌트 구현, 로케일별 메시지 추가, 미들웨어 로직 개선 등을 통해 목표를 달성했습니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 404 페이지 구현 및 로케일 처리와 직접 관련되어 있으며, 추가적인 범위 외 변경은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/proxy.ts`:
- Around line 37-39: The code reads NEXT_LOCALE from
request.cookies.get("NEXT_LOCALE") without validating it, allowing unsupported
locale values to be used in the rewrite; update the logic around
request.cookies.get("NEXT_LOCALE") so it checks
routing.locales.includes(cookieValue) and only uses the cookie when valid,
otherwise fall back to routing.defaultLocale, then pass that validated locale
into the locale variable used in NextResponse.rewrite (referencing NEXT_LOCALE,
request.cookies.get, routing.locales.includes, routing.defaultLocale, locale,
pathname, and NextResponse.rewrite).
🧹 Nitpick comments (1)
src/app/not-found.tsx (1)

10-13: 타입 단언(assertion)을 검증 전에 사용하는 것은 타입 안전성을 약화시킵니다.

쿠키 값은 외부 입력이므로 검증 전에 as LanguageType으로 단언하면 실제 값과 타입이 불일치할 수 있습니다. 검증 로직이 있어 런타임에는 안전하지만, 타입 가드를 활용하면 더 안전한 코드가 됩니다.

♻️ 타입 안전성 개선 제안
-  const localeCookie = cookieStore.get("NEXT_LOCALE")?.value as LanguageType | undefined;
-  const locale = localeCookie && routing.locales.includes(localeCookie)
-    ? localeCookie
-    : routing.defaultLocale;
+  const localeCookie = cookieStore.get("NEXT_LOCALE")?.value;
+  const locale = localeCookie && routing.locales.includes(localeCookie as LanguageType)
+    ? (localeCookie as LanguageType)
+    : routing.defaultLocale;

또는 타입 가드 함수를 별도로 만들어 재사용할 수 있습니다:

function isValidLocale(value: string | undefined): value is LanguageType {
  return !!value && routing.locales.includes(value as LanguageType);
}

@chaeyoungwon chaeyoungwon requested a review from ryu-won January 28, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[STUD-28] 404 페이지 UI 구현

2 participants