본문 바로가기
C.W.K.
Stream
Lesson 08 of 09 · published

국제화 라우팅 설계하기

~20 min · i18n, next-intl, locale

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

언어를 경로에 둘지 도메인에 둘지 골라

전략주소 형태
하위 경로/[locale]/page, 예를 들면 /en/about/ko/about
언어별 도메인en.example.comko.example.com

하위 경로는 배포와 SEO 신호를 한 도메인에서 관리하기 쉬운 기본 선택이야. 언어권마다 마케팅 팀이나 인프라가 완전히 분리돼 있다면 언어별 도메인이 의미 있을 수 있어.

협상 결과를 안정된 주소로 만들어

첫 방문에는 브라우저 언어와 쿠키를 보고 locale을 고를 수 있지만, 최종 콘텐츠는 공유할 수 있는 명시적 URL에 있어야 해. Proxy에서 한 번 리디렉션한 뒤 사용자가 고른 언어를 쿠키로 기억하는 방식이 흔해.

next-intl이 반복 작업을 묶어 줘

next-intl은 메시지 카탈로그, locale 협상, 날짜와 숫자 형식을 처리하고 서버·클라이언트 컴포넌트 양쪽에서 작동해. 단어 치환만이 아니라 복수형과 지역 형식을 같은 계약으로 관리할 수 있어.

번역 누락을 대체 언어로 숨기지 마

대체 언어는 장애 복구에는 유용하지만 누락을 영원히 감출 수 있어. 빌드나 검증 단계에서 locale별 키 집합을 비교해 콘텐츠 계약을 지켜.

지원 locale 목록을 라우팅, 메시지 카탈로그, metadata, sitemap이 한 canonical 설정에서 읽게 해. 새 언어를 추가할 때 URL 전환·서버 렌더링·클라이언트 상호작용·날짜·숫자·Open Graph를 한 흐름으로 시험해. 번역 키 집합 비교를 CI에 넣어 한쪽 누락을 바로 실패시켜. 언어 선택과 지역 선택을 한 값으로 뭉치지 마. 같은 한국어 사용자도 통화와 날짜 형식은 다른 지역 규칙을 원할 수 있으니 URL, 쿠키, 사용자 설정의 우선순위를 따로 시험해. locale을 URL에 넣었다고 국제화가 끝나는 건 아니야. 문장 길이, 복수형, 읽기 방향, 검색 색인, 공유 카드가 함께 바뀌어. 한 언어의 문장을 다른 언어 구조에 맞춰 복사하기보다 같은 사실을 각 언어가 자연스럽게 표현하도록 콘텐츠도 독립적으로 저작해야 해. 영어·한국어 URL을 직접 열고 언어 전환 뒤 새로고침·공유·뒤로 가기를 시험해. 메시지 키 하나를 일부러 누락해 CI가 실패하는지, 날짜·숫자·metadata·sitemap이 같은 locale을 따르는지, crawler가 각 언어 canonical과 alternate를 읽는지도 확인해.

Code

[locale] 아래의 언어별 레이아웃·tsx
// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  const messages = await getMessages();

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}
컴포넌트 안에서 번역 읽기·tsx
import { useTranslations } from 'next-intl';

export default function HomePage() {
  const t = useTranslations('Home');
  return (
    <>
      <h1>{t('title')}</h1>
      <p>{t('description')}</p>
    </>
  );
}

External links

Exercise

next-intl로 작은 페이지에 영어와 한국어를 추가해. URL 전환, 메시지·날짜·숫자·metadata가 두 locale에서 정확히 바뀌는지 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.