본문으로 건너뛰기
← 블로그로 돌아가기
개발 2026년 1월 10일

Astro i18n — 다국어 사이트 구현하기

Astro의 내장 i18n으로 한국어/영어 다국어 사이트를 만드는 실전 가이드.

Astro i18n 다국어 SEO

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 통합까지 자동이다.