콘텐츠로 건너뛰기
星罗
검색
언어 전환
뒤로 가기

국제화

1분 분량 GitHub에서 편집

Xingluo는 중영 이중 언어 UI 지원을 제공하며, prefixDefaultLocale: false 라우팅 전략을 사용하여 기본 언어에 URL 접두사가 없도록 합니다.

라우팅 전략

Astro의 i18n 구성(astro.config.ts 참조):

ts
i18n: { locales: ["zh-cn", "en"], defaultLocale: "zh-cn", routing: { prefixDefaultLocale: false }, }

중요: prefixDefaultLocale: false는 지역화된 페이지 복사본을 자동 생성하지 않습니다 — [locale]/ 미러 라우트를 수동으로 유지해야 합니다.

Xingluo의 접근 방식:

  • 루트 페이지 = 기본 언어(zh-cn), URL 접두사 없음(예: /posts/welcome/)
  • **src/pages/[locale]/**가 모든 페이지를 미러링합니다. getStaticPaths는 getLocaleParams()를 사용하여 기본값이 아닌 로케일만 생성(예: /en/posts/welcome/)
  • 미러 페이지도 얇은 래퍼이며, 동일한 View 컴포넌트를 렌더링 로직에 재사용합니다.
/ → 홈 (zh-cn) /en/ → 홈 (en) /posts/welcome/ → 게시물 (zh-cn) /en/posts/welcome/ → 게시물 (en)

로케일 확인

View 컴포넌트는 자동 확인을 위해 Astro.currentLocale을 사용합니다:

  • 루트 페이지 → zh-cn
  • [locale] 세그먼트 페이지 → en(또는 기타 기본값이 아닌 로케일)

컴포넌트 계층에서 경로 확인이 필요하지 않습니다. useTranslations(locale)이 해당 문자열을 직접 가져옵니다.

i18n 모듈 구조

src/i18n/:

파일책임
index.tsimport.meta.glob("./lang/*.ts", {eager:true})가 언어 로드; DEFAULT_LOCALE, LOCALES, useTranslations(locale), tplStr 내보내기
types.ts전체 UIStrings 인터페이스(로컬라이즈할 모든 문자열)
routing.tsgetLocalePrefix, withLocale(path, locale), parseLocaleFromPath(pathname)
staticPaths.tsNON_DEFAULT_LOCALES, getLocaleParams()
format.tstplStr(template, vars) — {{key}} 플레이스홀더 교체
lang/zh-cn.ts간체 중국어(기본값)
lang/en.ts영어

UIStrings 구조

UIStrings 인터페이스는 로컬라이즈할 모든 UI 문자열을 그룹별로 정의합니다:

  • nav: 탐색(홈/게시물/태그/소개/아카이브/검색/rss)
  • post: 게시물(날짜, 공유, 태그, 뒤로, 편집, 목차, 코드 복사, 이미지 라이트박스 등)
  • pagination: 페이지네이션
  • home: 홈페이지(소셜 링크, 추천, 최신)
  • archives: 아카이브(개수, 월)
  • footer: 푸터(저작권)
  • pages: 페이지 제목 및 설명
  • a11y: 접근성 레이블
  • languageSwitcher: 언어 전환기
  • notFound: 404
  • comments: 댓글 섹션

템플릿 문자열

플레이스홀더가 있는 문자열은 {{key}}를 사용하며 tplStr로 교체됩니다:

ts
import { tplStr } from "@/i18n"; // archives.postCount = "{{count}} posts" tplStr(t.archives.postCount, { count: 5 }); // "5 posts"

SEO 다국어 선언

Layout.astro의 head가 출력:

  • 각 언어별 <link rel="alternate" hreflang="..." href="...">
  • x-default는 기본 언어를 가리킴
  • 사이트맵 통합이 i18n 설정을 활성화하여 hreflang 자동 생성
  • 기본값이 아닌 로케일 게시물의 canonical은 기본 로케일 원본을 가리킴(중복 콘텐츠 페널티 방지, SEO 참조)

언어 추가

예: 일본어 ja 추가:

  1. astro.config.ts: i18n.locales에 "ja"를 추가하고 사이트맵 i18n.locales에 "ja": "ja-JP" 매핑 추가
  2. src/i18n/lang/: 완전한 UIStrings를 내보내는 ja.ts 생성(en.ts를 복사하여 번역)
  3. src/i18n/staticPaths.ts: NON_DEFAULT_LOCALES가 ja를 자동 포함(LOCALES에서 계산)
  4. src/pages/[locale]/: 미러 페이지가 자동으로 ja 버전 생성(getLocaleParams가 처리)
  5. 언어 전환기: zh-cn.ts와 en.ts의 languageSwitcher.names에 "ja": "日本語" 추가

콘텐츠 수준 번역

Xingluo는 locale 및 translationKey 프론트매터 필드를 통해 게시물의 다국어 콘텐츠를 지원합니다.

기본 사용법

  1. 기본 언어 게시물: src/content/posts/<slug>.md에 배치하고 translationKey를 그룹 식별자로 설정:

  2. 번역: 언어 하위 디렉토리 src/content/posts/<locale>/<slug>.md에 배치, 동일한 translationKey 사용:

디렉토리 구조

src/content/posts/ ├── welcome.md # 기본 언어 (zh-cn) ├── en/ │ └── welcome.md # 영어 번역 ├── ja/ │ └── welcome.md # 일본어 번역 └── another-post.md # 독립 게시물 (translationKey 없음)
  • 언어 하위 디렉토리 이름은 astro.config.ts의 i18n.locales 언어 코드와 일치해야 함
  • 언어 하위 디렉토리는 URL 슬러그에서 필터링됨(예: /posts/welcome/, /posts/en/welcome/ 아님)
  • translationKey가 없는 게시물은 독립적이며 언어 간 연결되지 않음

라우팅 동작

시나리오동작
기본 로케일에서 zh-cn 게시물 접근기본 언어 원본 렌더링
번역이 있는 비기본 로케일해당 번역 렌더링
번역이 없는 비기본 로케일기본 언어 원본으로 폴백(동일 콘텐츠, canonical이 SEO 보호)

목록 중복 제거

목록 페이지(홈, 게시물 목록, 태그, 아카이브, RSS)는 getPostsForLocale을 사용하여 언어별 대표 게시물을 선택합니다. 각 번역 그룹은 대상 언어로 하나의 카드만 표시하여 동일 주제의 중복 항목을 방지합니다.

canonical 및 SEO

  • 독립 번역이 있는 경우: canonical은 번역 자체 URL을 가리키며 검색 엔진이 개별적으로 인덱싱 가능
  • 번역이 없는 경우(폴백): canonical은 기본 언어 원본을 가리켜 중복 콘텐츠 페널티 방지
  • hreflang 선언이 모든 언어를 포괄하여 언어 버전 간의 관계를 검색 엔진에 전달

SEO 참조.


관련 글

  • 배포

    1분 분량

    Xingluo 배포 가이드 - 정적 호스팅 플랫폼(Netlify/Vercel/GitHub Pages), Nginx 자체 호스팅, Docker 및 환경 변수.

  • 검색

    1분 분량

    Xingluo 검색 가이드 - Flexsearch 전체 텍스트 검색 통합, 인덱스 생성, UI, 다국어 검색 및 성능.