Astro i18n — 다국어 사이트 구현하기
Astro의 내장 i18n으로 한국어/영어 다국어 사이트를 만드는 실전 가이드.
Astro의 i18n 지원
Astro 4부터 i18n이 내장됐다. 별도 플러그인 없이 astro.config.mjs에서 설정하면 된다.
export default defineConfig({
i18n: {
defaultLocale: 'ko',
locales: ['ko', 'en'],
routing: {
prefixDefaultLocale: false,
redirectToDefaultLocale: false,
},
fallback: { en: 'ko' },
},
});
이 설정의 의미:
- defaultLocale: ‘ko’: 한국어가 기본
- prefixDefaultLocale: false: 한국어는
/about/, 영어는/en/about/ - fallback:
{ en: 'ko' }— 영어 번역이 없으면 한국어로 폴백
URL 구조
karnellabs.com/ → 한국어 홈
karnellabs.com/about/ → 한국어 소개
karnellabs.com/en/ → 영어 홈
karnellabs.com/en/about/ → 영어 소개
기본 언어에 prefix를 붙이지 않는 이유: 대부분의 사용자가 한국어이므로, URL을 깔끔하게 유지한다. /ko/about/ 대신 /about/.
번역 파일
JSON 파일로 번역을 관리한다.
// src/i18n/ko.json
{
"nav.services": "서비스",
"nav.portfolio": "작업물",
"nav.blog": "블로그",
"hero.headline": "만들고, 배포하고, 운영합니다."
}
// src/i18n/en.json
{
"nav.services": "Services",
"nav.portfolio": "Work",
"nav.blog": "Blog",
"hero.headline": "Build. Ship. Operate."
}
유틸리티 함수
// src/i18n/utils.ts
export type Lang = 'ko' | 'en';
const dictionaries: Record<Lang, Record<string, string>> = { ko, en };
export function getLangFromUrl(url: URL): Lang {
const [, lang] = url.pathname.split('/');
return lang === 'en' ? 'en' : 'ko';
}
export function useTranslations(lang: Lang) {
return function t(key: string): string {
return dictionaries[lang]?.[key] ?? dictionaries.ko[key] ?? key;
};
}
export function getLocalePath(lang: Lang, path: string): string {
const cleanPath = path.startsWith('/') ? path : `/${path}`;
return lang === 'ko' ? cleanPath : `/en${cleanPath}`;
}
useTranslations는 React Hook이 아니라 순수 함수다. Astro 컴포넌트의 frontmatter에서 호출한다.
컴포넌트에서 사용
---
import { getLangFromUrl, useTranslations } from '@i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
---
<h1>{t('hero.headline')}</h1>
페이지 구조
한국어와 영어 페이지를 각각 만든다.
src/pages/
├── index.astro # 한국어 홈
├── about.astro # 한국어 소개
├── blog/
│ ├── index.astro
│ └── [slug].astro
└── en/
├── index.astro # 영어 홈
├── about.astro # 영어 소개
└── blog/
├── index.astro
└── [slug].astro
영어 페이지는 한국어와 동일한 구조를 en/ 폴더 아래에 복제한다. 레이아웃과 컴포넌트는 공유하고, lang 파라미터만 다르다.
SEO: hreflang 태그
검색 엔진에 언어별 페이지 관계를 알려주기 위해 hreflang 태그를 추가한다.
<link rel="alternate" hreflang="ko" href="https://karnellabs.com/about/" />
<link rel="alternate" hreflang="en" href="https://karnellabs.com/en/about/" />
이 태그가 있으면 Google이 사용자의 언어 설정에 맞는 페이지를 검색 결과에 보여준다.
Sitemap 연동
@astrojs/sitemap 플러그인이 자동으로 hreflang이 포함된 sitemap을 생성한다.
sitemap({
i18n: {
defaultLocale: 'ko',
locales: { ko: 'ko-KR', en: 'en-US' },
},
}),
콘텐츠 컬렉션에서의 i18n
블로그 글이나 포트폴리오는 콘텐츠 파일을 언어별로 분리하지 않았다. 대신 하나의 MDX 파일에 양쪽 언어를 넣는다.
title: "KeyBox"
titleEn: "KeyBox"
description: "개발자용 시크릿 매니저"
descriptionEn: "Developer secret manager"
영어 페이지에서는 titleEn, descriptionEn을 사용하고, 본문(MDX body)은 한국어로 작성한다. 콘텐츠가 적을 때는 이 방식이 파일 관리 측면에서 효율적이다.
정리
Astro의 내장 i18n은 폴더 기반 라우팅 + JSON 번역 파일로 깔끔하게 동작한다. 라이브러리 의존성 없이 다국어 사이트를 구축할 수 있고, sitemap과 hreflang 통합까지 자동이다.