테마 전환

Astro i18n 설정 가이드: 30분 만에 다국어 웹사이트 구현하기(언어 전환기 포함)

Easton editorial illustration: monorepo project desk

멋지게 만든 Astro 블로그를 해외 시장에 선보이려는데 다국어 지원 방법을 몰라 막막할 수 있습니다. locales, defaultLocale, prefixDefaultLocale 같은 설정 항목은 이해하기 어렵고, 다국어 콘텐츠를 어떻게 구성해야 할지도 모르겠고, Content Collections가 무엇인지도 낯설며, 언어 전환기는 어디서부터 시작해야 할지 감이 잡히지 않습니다.

Astro의 i18n 설정은 그렇게 복잡하지 않습니다. 공식 문서가 다소 기술적으로 쓰여 있을 뿐입니다. 이 글에서는 기본 설정부터 언어 전환기까지 Astro i18n 설정의 전체 과정을 다룹니다. 모든 단계에 완전한 코드를 제공하므로 30분 안에 웹사이트에 다국어 지원을 추가할 수 있습니다.

Astro i18n 기본 설정(10분이면 완료)

astro.config.mjs 설정 자세히 알아보기

가장 중요한 설정 파일부터 살펴보겠습니다. Astro는 v4.0부터 i18n을 기본 지원하며 설정도 꽤 간단합니다. astro.config.mjs를 열고 다음 코드를 추가하세요.

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  i18n: {
    // 웹사이트가 지원하는 언어를 Astro에 알립니다.
    locales: ['en', 'zh-cn', 'ja'],

    // 기본 언어(locales 중 하나여야 합니다.)
    defaultLocale: 'en',

    // 기본 언어에 경로 접두사를 붙일지 여부
    prefixDefaultLocale: false,
  }
});

각 설정 항목을 하나씩 살펴보겠습니다.

locales - 웹사이트가 지원하는 모든 언어입니다. 'en'(영어), 'zh-cn'(중국어 간체), 'ja'(일본어) 같은 표준 언어 코드를 사용하면 됩니다. 언어를 더 세밀하게 구분해야 한다면 'en-US', 'en-GB'처럼 작성할 수도 있습니다.

defaultLocale - 방문자가 웹사이트에 처음 들어왔을 때 표시되는 기본 언어입니다. 이 값은 반드시 locales 배열에 포함되어야 하며, 그렇지 않으면 Astro에서 오류가 발생합니다.

prefixDefaultLocale - 저도 처음에는 선택을 오래 고민했던 설정입니다. false로 설정하면 기본 언어 URL에는 언어 접두사가 붙지 않고(예: /about), 다른 언어에만 접두사가 붙습니다(예: /zh-cn/about, /ja/about). true로 설정하면 모든 언어에 접두사가 붙습니다(/en/about, /zh-cn/about).

대부분은 false면 충분합니다. 기본 언어 URL이 더 간결해지기 때문입니다. URL 형식의 통일성이 특히 중요하거나 SEO 관련 요구가 있다면 true를 고려할 수 있습니다.

세 가지 라우팅 전략 비교

Astro의 i18n 라우팅에는 세 가지 전략이 있습니다. 다음 표를 보고 프로젝트에 어떤 방식이 적합한지 비교해 보세요.

전략설정 방법URL 예시적합한 상황장단점
전략 1: 기본 언어에 접두사 없음prefixDefaultLocale: false/about
/zh-cn/about
/ja/about
대부분의 웹사이트(권장)✅ 기본 언어 URL이 간결함
❌ URL 형식이 통일되지 않음
전략 2: 모든 언어에 접두사 사용prefixDefaultLocale: true/en/about
/zh-cn/about
/ja/about
URL 통일성이 필요하거나
특별한 SEO 요구가 있는 경우
✅ URL 형식이 통일됨
✅ 언어 전환 로직이 단순함
❌ 기본 언어 URL이 조금 길어짐
전략 3: 수동 모드routing: 'manual'완전히 사용자 지정복잡한 다국어 요구 사항
라우팅을 완전히 제어해야 하는 경우
✅ 유연성이 높음
❌ 설정이 복잡하고 많은 로직을 직접 처리해야 함

프로젝트가 블로그나 문서 사이트처럼 비교적 단순하다면 전략 1을 바로 사용하는 것이 좋습니다. URL 형식을 깔끔하게 통일하고 싶다면 전략 2를 사용하세요. 전략 3은 사용자 행동에 따라 언어를 동적으로 선택하거나 서로 다른 하위 도메인에서 다른 언어를 제공해야 하는 등 특별한 요구가 있는 프로젝트에 적합합니다.

여기까지 읽고 중국어와 영어를 지원하는 블로그만 만들고 싶은데 위 설정을 복사해 조금만 수정하면 되는지 궁금할 수 있습니다. 맞습니다. 그렇게 간단합니다. locales['zh-cn', 'en']으로 바꾸고, 주요 독자가 중국어 사용자라고 가정한다면 defaultLocale'zh-cn'으로 설정하면 끝입니다.

Astro i18n 다국어 지원 설정

30분 만에 Astro 웹사이트의 다국어 설정을 구현하는 전체 단계

  1. 1

    Step 1: astro.config.mjs 설정

    astro.config.mjs에 i18n 설정을 추가합니다.
  2. 2

    Step 2: 다국어 콘텐츠 구성

    콘텐츠 구성 방법을 선택합니다.
  3. 3

    Step 3: UI 번역 사전 만들기

    src/i18n/ui.ts에 번역 사전을 만듭니다.
  4. 4

    Step 4: 언어 전환기 구현

    getRelativeLocaleUrl과 Astro.currentLocale로 언어 전환 컴포넌트를 만듭니다.
  5. 5

    Step 5: SEO 최적화

    Layout에 hreflang 태그를 추가하고 sitemap을 설정하며 meta 정보를 현지화합니다.

다국어 콘텐츠 구성(두 가지 방법 중 선택)

설정을 마쳤다면 이제 다국어 콘텐츠를 어떻게 구성할지 결정해야 합니다. 많은 사람이 파일을 어디에 두어야 하는지 몰라 이 단계에서 막힙니다. Astro는 두 가지 방법을 제공하므로 익숙한 방식을 선택하면 됩니다.

방법 1: 언어별 폴더 구성(초보자에게 권장)

가장 직관적인 방법입니다. 다음과 같이 언어마다 하나의 폴더를 만듭니다.

src/pages/
├── about.astro        # 기본 언어(중국어라고 가정)
├── blog.astro
├── index.astro
├── en/                # 영어 버전
│   ├── about.astro
│   ├── blog.astro
│   └── index.astro
└── ja/                # 일본어 버전
    ├── about.astro
    ├── blog.astro
    └── index.astro

prefixDefaultLocale: false(기본 언어에 접두사 없음)를 사용한다면 기본 언어 파일은 pages 루트 디렉터리에 바로 둡니다. 다른 언어에만 해당 하위 폴더를 만들어야 합니다.

이 방법은 구조가 명확하고 언어별 페이지가 독립되어 있어 한쪽을 수정해도 다른 쪽에 영향을 주지 않는다는 장점이 있습니다. 하지만 페이지가 많아지면 파일과 코드가 대량으로 중복됩니다. 예를 들어 페이지 20개와 언어 5개를 지원한다면 파일 100개를 관리해야 하니 생각만 해도 부담스럽습니다.

방법 2: 동적 라우팅(고급 사용자에게 권장)

방법 1이 너무 번거롭다면 동적 라우팅을 사용해 보세요. 파일 하나로 모든 언어를 처리할 수 있습니다.

src/pages/
└── [lang]/
    └── [...slug].astro

그런 다음 [...slug].astro에서 lang 매개변수에 따라 콘텐츠를 동적으로 렌더링합니다.


---

// src/pages/[lang]/[...slug].astro
export function getStaticPaths() {
  const locales = ['zh-cn', 'en', 'ja'];
  const slugs = ['about', 'blog', 'contact'];

  return locales.flatMap((lang) =>
    slugs.map((slug) => ({
      params: { lang, slug },
    }))
  );
}

const { lang, slug } = Astro.params;
// lang과 slug에 따라 해당 콘텐츠를 불러옵니다.

---

이 방식은 코드 재사용성이 높고 유지보수 비용이 낮지만 Astro의 동적 라우팅 로직을 이해해야 합니다. Astro를 처음 사용한다면 먼저 방법 1로 익숙해진 뒤 방법 2를 고려하는 것이 좋습니다.

Content Collections 다국어 구성(블로그 필수)

지금까지 페이지 파일을 중심으로 설명했지만, 블로그에서는 Content Collections가 핵심입니다. Astro가 권장하는 콘텐츠 관리 방식이며 블로그나 문서처럼 콘텐츠 중심인 웹사이트에 특히 적합합니다.

디렉터리 구조는 다음과 같습니다.

src/content/
└── blog/
    ├── en/
    │   ├── post-1.md
    │   └── post-2.md
    ├── zh-cn/
    │   ├── post-1.md
    │   └── post-2.md
    └── ja/
        ├── post-1.md
        └── post-2.md

그런 다음 src/content/config.ts에서 schema를 정의합니다.

// src/content/config.ts
import { defineCollection, z } from 'astro:content';

const blogCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    author: z.string(),
    date: z.date(),
    lang: z.enum(['en', 'zh-cn', 'ja']),  // 언어 필드
  }),
});

export const collections = {
  blog: blogCollection,
};

페이지에서 해당 언어의 글을 가져옵니다.


---

// src/pages/blog/index.astro
import { getCollection } from 'astro:content';

const currentLang = Astro.currentLocale;  // 현재 언어 가져오기
const posts = await getCollection('blog', ({ data }) => {
  return data.lang === currentLang;  // 현재 언어의 글만 가져오기
});

---

이제 사용자가 선택한 언어에 맞는 글을 자동으로 표시할 수 있습니다. Astro 공식 문서 사이트도 이 방식으로 다국어 콘텐츠를 관리하므로 신뢰하고 사용할 수 있습니다.

UI 번역 파일 관리

콘텐츠 파일 외에도 내비게이션 바, 버튼, 폼 레이블 같은 고정 UI 텍스트를 번역해야 합니다. 다음과 같은 번역 사전을 만드는 것을 권장합니다.

// src/i18n/ui.ts
export const ui = {
  'en': {
    'nav.home': 'Home',
    'nav.about': 'About',
    'nav.blog': 'Blog',
    'btn.readMore': 'Read More',
  },
  'zh-cn': {
    'nav.home': '首页',
    'nav.about': '关于',
    'nav.blog': '博客',
    'btn.readMore': '阅读更多',
  },
  'ja': {
    'nav.home': 'ホーム',
    'nav.about': '概要',
    'nav.blog': 'ブログ',
    'btn.readMore': '続きを読む',
  },
} as const;

이어서 두 개의 헬퍼 함수를 작성합니다.

// src/i18n/utils.ts
import { ui } from './ui';

// URL에서 현재 언어 가져오기
export function getLangFromUrl(url: URL) {
  const [, lang] = url.pathname.split('/');
  if (lang in ui) return lang as keyof typeof ui;
  return 'zh-cn';  // 기본 언어
}

// 번역 함수 가져오기
export function useTranslations(lang: keyof typeof ui) {
  return function t(key: keyof typeof ui[typeof lang]) {
    return ui[lang][key] || ui['zh-cn'][key];
  }
}

컴포넌트에서는 다음과 같이 사용합니다.


---

// 임의의 컴포넌트
import { getLangFromUrl, useTranslations } from '@/i18n/utils';

const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);

---

<nav>
  <a href="/">{t('nav.home')}</a>
  <a href="/about">{t('nav.about')}</a>
  <a href="/blog">{t('nav.blog')}</a>
</nav>

이 방식은 간단하면서도 실용적입니다. 번역을 한 파일에 모아 두므로 수정하기도 편합니다. 번역 텍스트가 특히 많다면 여러 JSON 파일로 나눠 모듈별로 관리할 수도 있습니다.

언어 전환기 구현하기(전체 코드 포함)

설정과 콘텐츠 구성을 마쳤으니 이제 가장 중요한 언어 전환기를 구현할 차례입니다. 솔직히 저도 처음에는 이 부분이 가장 어려워 여러 웹사이트의 구현을 살펴본 뒤에야 이해했습니다. 하지만 Astro의 helper 함수를 이해하고 나면 꽤 간단합니다.

Astro i18n helper 함수 이해하기

Astro는 다국어 URL을 처리하기 위한 매우 유용한 함수 몇 가지를 제공합니다. 먼저 각 함수를 살펴보겠습니다.

getRelativeLocaleUrl(locale, path) - 특정 언어의 상대 경로를 가져옵니다.

import { getRelativeLocaleUrl } from 'astro:i18n';

// 영어 버전 소개 페이지의 URL 가져오기
const url = getRelativeLocaleUrl('en', 'about');
// 반환값: '/en/about' 또는 '/about'(설정에 따라 다름)

getAbsoluteLocaleUrl(locale, path) - 절대 경로, 즉 도메인을 포함한 전체 URL을 가져옵니다.

import { getAbsoluteLocaleUrl } from 'astro:i18n';

const url = getAbsoluteLocaleUrl('en', 'about');
// 반환값: 'https://example.com/en/about'

Astro.currentLocale - 현재 페이지의 언어를 가져옵니다.


---

const currentLang = Astro.currentLocale;
// 반환값: 'zh-cn', 'en' 등

---

Astro.preferredLocale - 웹사이트에서 지원하는 경우 사용자 브라우저의 기본 언어를 가져옵니다.


---

const browserLang = Astro.preferredLocale;
// 반환값: locales에 포함된 경우 사용자의 브라우저 설정 언어

---

이 도구들을 이용하면 언어 전환기 구현을 시작할 수 있습니다.

언어 전환 컴포넌트 만들기

바로 복사해서 사용할 수 있는 간단하고 실용적인 언어 전환기를 만들어 보았습니다.


---

// src/components/LanguageSwitcher.astro
import { getRelativeLocaleUrl } from 'astro:i18n';

// 지원하는 모든 언어(설정 파일에서 읽어오는 편이 좋지만 여기서는 예시를 위해 직접 작성합니다.)
const locales = {
  'zh-cn': '简体中文',
  'en': 'English',
  'ja': '日本語',
};

// 현재 언어와 경로 가져오기
const currentLang = Astro.currentLocale || 'zh-cn';
const currentPath = Astro.url.pathname
  .replace(`/${currentLang}/`, '/')  // 언어 접두사 제거
  .replace(/^\//, '');  // 앞쪽 슬래시 제거

---

<div class="language-switcher">
  <button class="lang-button">
    {locales[currentLang]} ▼
  </button>
  <div class="lang-dropdown">
    {Object.entries(locales).map(([lang, label]) => {
      const url = getRelativeLocaleUrl(lang, currentPath);
      return (
        <a
          href={url}
          class={lang === currentLang ? 'active' : ''}
        >
          {label}
        </a>
      );
    })}
  </div>
</div>

<style>
  .language-switcher {
    position: relative;
    display: inline-block;
  }

  .lang-button {
    padding: 8px 16px;
    background: #f3f4f6;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    cursor: pointer;
  }

  .lang-button:hover {
    background: #e5e7eb;
  }

  .lang-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 4px;
    background: white;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    min-width: 150px;
  }

  .language-switcher:hover .lang-dropdown {
    display: block;
  }

  .lang-dropdown a {
    display: block;
    padding: 10px 16px;
    color: #374151;
    text-decoration: none;
    transition: background 0.2s;
  }

  .lang-dropdown a:hover {
    background: #f3f4f6;
  }

  .lang-dropdown a.active {
    background: #dbeafe;
    color: #1e40af;
    font-weight: 500;
  }
</style>

<script>
  // 모바일에서 클릭으로 전환
  document.querySelector('.lang-button')?.addEventListener('click', (e) => {
    e.stopPropagation();
    const dropdown = document.querySelector('.lang-dropdown');
    dropdown?.classList.toggle('show');
  });

  // 다른 곳을 클릭하면 닫기
  document.addEventListener('click', () => {
    document.querySelector('.lang-dropdown')?.classList.remove('show');
  });
</script>

사용할 때는 Layout이나 내비게이션 바에서 불러옵니다.


---

// src/layouts/Layout.astro
import LanguageSwitcher from '@/components/LanguageSwitcher.astro';

---

<header>
  <nav>
    <!-- 기타 내비게이션 항목 -->
    <LanguageSwitcher />
  </nav>
</header>

이 컴포넌트의 핵심 로직은 다음과 같습니다.

  1. 현재 언어와 경로를 가져옵니다.
  2. 지원하는 언어별로 해당 URL을 생성합니다.
  3. 현재 언어를 강조 표시합니다.
  4. 클릭하면 해당 언어의 페이지로 전환합니다.

getRelativeLocaleUrl(lang, currentPath)로 URL을 생성한 점을 눈치챘을지도 모릅니다. 이렇게 하면 언어를 전환한 뒤에도 홈페이지로 돌아가지 않고 같은 페이지의 다른 언어 버전에 머물 수 있습니다.

브라우저 언어 감지(선택 사항이지만 권장)

사용자가 처음 방문했을 때 브라우저에 설정된 언어로 자동 이동시키고 싶을 수 있습니다. middleware로 이를 구현할 수 있습니다.

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware((context, next) => {
  const url = context.url;
  const currentLocale = context.currentLocale;
  const preferredLocale = context.preferredLocale;

  // 루트 경로에 접근했고 브라우저 언어가 현재 언어와 다르면 자동으로 리디렉션합니다.
  if (url.pathname === '/' && preferredLocale && preferredLocale !== currentLocale) {
    return context.redirect(`/${preferredLocale}/`);
  }

  return next();
});

이제 사용자가 처음 방문하면 익숙한 언어로 자동 이동합니다. 다만 매번 강제로 리디렉션해서는 안 됩니다. 사용자가 언어를 직접 바꾼 뒤에도 다시 이전 언어로 돌아가 버리면 경험이 매우 나빠집니다.

더 나은 방법은 Cookie를 사용해 사용자의 선택을 기억하는 것입니다.

// 개선된 middleware
export const onRequest = defineMiddleware((context, next) => {
  const url = context.url;
  const currentLocale = context.currentLocale;
  const preferredLocale = context.preferredLocale;
  const savedLang = context.cookies.get('user-lang')?.value;

  // 사용자가 저장한 언어 설정을 우선 사용합니다.
  if (savedLang && savedLang !== currentLocale && url.pathname === '/') {
    return context.redirect(`/${savedLang}/`);
  }

  // 저장된 설정이 없으면 브라우저 언어를 사용합니다.
  if (!savedLang && url.pathname === '/' && preferredLocale && preferredLocale !== currentLocale) {
    context.cookies.set('user-lang', preferredLocale, {
      path: '/',
      maxAge: 31536000,  // 1년
    });
    return context.redirect(`/${preferredLocale}/`);
  }

  return next();
});

그런 다음 언어 전환기에서도 언어를 바꿀 때 Cookie를 업데이트합니다.

<script>
  document.querySelectorAll('.lang-dropdown a').forEach((link) => {
    link.addEventListener('click', (e) => {
      const lang = e.target.getAttribute('data-lang');
      document.cookie = `user-lang=${lang}; path=/; max-age=31536000`;
    });
  });
</script>

이렇게 하면 사용자의 언어 설정을 기억해 다음 방문 때 선택한 언어를 바로 표시할 수 있습니다.

고급 팁(fallback, 도메인 매핑, SEO)

기본 기능을 모두 구현했으니 몇 가지 고급 팁을 살펴보겠습니다. 프로젝트가 비교적 단순하다면 이 부분은 건너뛰었다가 필요할 때 다시 확인해도 됩니다.

Fallback 전략 설정

웹사이트 콘텐츠를 점진적으로 번역하고 있어 일부 페이지의 일본어 버전이 아직 완성되지 않았다고 가정해 보겠습니다. 사용자가 존재하지 않는 일본어 페이지를 방문했을 때 영어 버전을 대체 콘텐츠로 보여 주고 싶을 수 있습니다. 이것이 fallback 전략입니다.

// astro.config.mjs
export default defineConfig({
  i18n: {
    locales: ['en', 'zh-cn', 'ja'],
    defaultLocale: 'en',
    fallback: {
      ja: 'en',      // 일본어가 없으면 영어 표시
      'zh-cn': 'en', // 중국어가 없어도 영어 표시
    },
  }
});

이렇게 설정하면 /ja/some-page가 없을 때 Astro는 404 페이지 대신 /en/some-page의 콘텐츠를 자동으로 표시합니다. 아직 콘텐츠 번역을 진행 중인 웹사이트에 특히 유용한 기능입니다.

사용자 지정 도메인 매핑

일부 글로벌 제품은 다음과 같이 언어마다 다른 도메인을 설정합니다.

  • 영어: example.com
  • 중국어: example.cn
  • 일본어: example.jp

Astro도 이를 지원하지만 도메인 매핑은 SSR(서버 사이드 렌더링) 모드에서만 사용할 수 있다는 점에 유의하세요.

// astro.config.mjs
export default defineConfig({
  output: 'server',  // SSR을 반드시 활성화해야 합니다.
  adapter: node(),   // 어댑터 설정 필요
  i18n: {
    locales: ['en', 'zh-cn', 'ja'],
    defaultLocale: 'en',
    domains: {
      'zh-cn': 'https://example.cn',
      ja: 'https://example.jp',
    },
  }
});

설정 후 중국어 콘텐츠는 example.cn에, 일본어 콘텐츠는 example.jp에 자동 배포됩니다. 프로젝트가 정적 웹사이트(기본 모드)라면 이 기능을 사용할 수 없습니다.

SEO 최적화 핵심 사항

다국어 웹사이트의 SEO 최적화에서 핵심은 검색 엔진에 이 페이지의 언어별 버전이 무엇인지 알려 주는 것입니다. 가장 중요한 요소는 hreflang 태그입니다.

다행히 Astro는 i18n SEO를 매우 잘 지원하므로 올바르게 설정하기만 하면 많은 작업이 자동으로 처리됩니다. 다만 몇 가지는 직접 처리해야 합니다.

1. Layout에 hreflang 태그 추가


---

// src/layouts/Layout.astro
import { getAbsoluteLocaleUrl } from 'astro:i18n';

const locales = ['en', 'zh-cn', 'ja'];
const currentPath = Astro.url.pathname
  .replace(/^\/(en|zh-cn|ja)\//, '')
  .replace(/^\//, '');

---

<html>
<head>
  <!-- 언어별 hreflang 태그 추가 -->
  {locales.map((lang) => (
    <link
      rel="alternate"
      hreflang={lang}
      href={getAbsoluteLocaleUrl(lang, currentPath)}
    />
  ))}

  <!-- 기본 언어 태그 추가 -->
  <link
    rel="alternate"
    hreflang="x-default"
    href={getAbsoluteLocaleUrl('en', currentPath)}
  />

  <!-- meta 설명 현지화 -->
  <meta name="description" content={description[currentLang]} />

  <!-- 표준 URL -->
  <link rel="canonical" href={getAbsoluteLocaleUrl(currentLang, currentPath)} />
</head>
</html>

2. sitemap.xml 다국어 설정

@astrojs/sitemap 플러그인을 사용하면 언어별 sitemap이 자동으로 생성됩니다. site 매개변수만 설정하면 됩니다.

// astro.config.mjs
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',  // 반드시 설정
  integrations: [sitemap()],
});

3. meta 정보 현지화

title, description, keywords 같은 meta 정보도 해당 언어로 번역해야 합니다.


---

const meta = {
  'en': {
    title: 'Welcome to My Blog',
    description: 'A blog about web development',
  },
  'zh-cn': {
    title: '欢迎来到我的博客',
    description: '一个关于 Web 开发的博客',
  },
};

const currentLang = Astro.currentLocale || 'en';

---

<head>
  <title>{meta[currentLang].title}</title>
  <meta name="description" content={meta[currentLang].description} />
</head>

이 세 가지를 잘 처리하면 검색 엔진이 다국어 웹사이트를 올바르게 색인할 수 있습니다.

결론

지금까지 설명한 Astro i18n 설정 과정을 정리해 보겠습니다.

1단계: astro.config.mjs 설정(5분)

  • locales 배열(지원하는 언어)을 설정합니다.
  • defaultLocale(기본 언어)을 설정합니다.
  • 요구 사항에 따라 prefixDefaultLocale 전략을 선택합니다.

2단계: 다국어 콘텐츠 구성(자신에게 맞는 방법 선택)

  • 초보자 권장: 언어별 폴더 구성
  • 고급 사용자 권장: 동적 라우팅 + Content Collections
  • UI 번역 사전 설정도 잊지 마세요.

3단계: 언어 전환기 구현(코드를 복사해 바로 사용)

  • getRelativeLocaleUrl로 URL을 생성합니다.
  • Astro.currentLocale로 현재 언어를 가져옵니다.
  • 선택 사항: 브라우저 언어 감지와 Cookie 저장 기능을 추가합니다.

Astro i18n을 한동안 사용해 보니 정말 편리했습니다. 설정이 간단하고 helper 함수도 사용하기 좋으며 성능도 뛰어납니다. 모든 언어의 라우트가 빌드 시 미리 생성되기 때문입니다. 웹사이트에서 다국어를 지원해야 한다면 Astro의 기본 제공 방식을 충분히 시도해 볼 만합니다.

지금 바로 Astro 웹사이트에 다국어 지원을 추가해 보세요. 문제가 생기면 더 자세한 API 설명이 있는 Astro 공식 i18n 문서를 확인하면 됩니다.

실전 경험이나 시행착오가 있다면 댓글로 공유해 주세요. 함께 이야기하며 배워 봅시다.

FAQ

Astro i18n 설정에는 얼마나 걸리나요?
기본 설정은 5~10분이면 충분합니다.
• astro.config.mjs에서 locales, defaultLocale, prefixDefaultLocale을 설정하는 과정이 포함됩니다.

언어 전환기와 SEO 최적화를 포함한 완전한 다국어 웹사이트 구현에는 약 30분이 걸립니다.
prefixDefaultLocale은 true와 false 중 무엇으로 설정해야 하나요?
대부분의 경우 false로 설정하면 됩니다.
• 기본 언어 URL이 /about처럼 더 간결해집니다.

URL 형식을 통일해야 하거나 특별한 SEO 요구가 있다면 /en/about처럼 true로 설정할 수 있습니다.
다국어 콘텐츠는 어떻게 구성하나요?
두 가지 방법이 있습니다.

방법 1은 언어별로 폴더를 나누는 방식으로, 초보자에게 권장합니다.
• 구조가 명확하지만 파일 수가 많아집니다.

방법 2는 동적 라우팅 방식으로, 고급 사용자에게 권장합니다.
• 코드 재사용성이 높고 유지보수 비용이 낮습니다.

블로그에서는 Content Collections로 다국어 글을 관리하는 것이 좋습니다.
언어 전환기는 어떻게 구현하나요?
Astro가 제공하는 getRelativeLocaleUrl 함수로 다국어 URL을 생성하고 Astro.currentLocale로 현재 언어를 가져옵니다.

브라우저 언어 감지와 Cookie 저장 기능을 함께 사용하면 사용자 경험을 개선할 수 있습니다.
다국어 웹사이트의 SEO는 어떻게 최적화하나요?
주요 단계는 다음과 같습니다.
• Layout에 hreflang 태그를 추가해 각 언어 버전을 검색 엔진에 알립니다.
• sitemap 플러그인을 설정해 다국어 sitemap을 자동으로 생성합니다.
• title, description 같은 meta 정보를 현지화합니다.

Astro는 i18n SEO를 잘 지원하므로 많은 작업이 자동으로 처리됩니다.

5분 읽기 · 게시일: 2025년 12월 2일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog