국제화 기능 추가
이 레시피에서는 콘텐츠 컬렉션과 동적 라우팅을 사용하여 자체 국제화 (i18n) 솔루션을 구축하고 콘텐츠를 다양한 언어로 제공하는 방법을 배웁니다.
v4.0에서 Astro는 기본 및 지원되는 언어를 구성할 수 있게 해주는 i18n 라우팅에 대한 내장 지원을 추가했으며, 국제 청중에게 서비스를 제공하는 데 도움이 되는 귀중한 도우미 기능을 포함하고 있습니다. 대신 이 기능을 사용하려면 국제화 가이드를 참조하여 이러한 기능에 대해 알아보세요.
이 예시는 자체 하위 경로에서 각 언어를 제공합니다. 영어의 경우 example.com/en/blog, 프랑스어의 경우 example.com/fr/blog입니다.
다른 언어와 달리 기본 언어가 URL에 표시되지 않도록 하려면 아래의 기본 언어를 숨기는 방법을 참조하세요.
레시피
섹션 제목: “레시피”언어별 페이지 설정
섹션 제목: “언어별 페이지 설정”-
지원하려는 각 언어에 대한 디렉터리를 만듭니다. 예를 들어, 영어와 프랑스어를 지원하는 경우
en/및fr/:디렉터리src/
디렉터리pages/
디렉터리en/
- about.astro
- index.astro
디렉터리fr/
- about.astro
- index.astro
- index.astro
-
기본 언어로 리디렉션하려면
src/pages/index.astro를 설정하세요.src/pages/index.astro <meta http-equiv="refresh" content="0;url=/en/" />이 접근 방식은 meta refresh를 사용하며 사이트를 배포하는 방식에 따라 작동합니다. 일부 정적 호스트에서는 사용자 정의 구성 파일을 사용하여 서버 리디렉션을 구성할 수도 있습니다. 자세한 내용은 배포 플랫폼의 설명서를 참조하세요.
SSR 어댑터를 사용하는 경우
Astro.redirect를 사용하여 서버의 기본 언어로 리디렉션할 수 있습니다.src/pages/index.astro ---return Astro.redirect('/en/');---
번역된 콘텐츠에 컬렉션 사용
섹션 제목: “번역된 콘텐츠에 컬렉션 사용”-
포함하려는 각 콘텐츠 유형에 대해
src/content/에 폴더를 만들고 지원되는 각 언어에 대한 하위 디렉터리를 추가합니다. 예를 들어 영어 및 프랑스어 블로그 게시물을 지원하려면 다음을 수행하세요.디렉터리src/
디렉터리content/
디렉터리blog/
디렉터리en/ 영어로 된 블로그 게시물
- post-1.md
- post-2.md
디렉터리fr/ 프랑스어로 된 블로그 게시물
- post-1.md
- post-2.md
-
src/content.config.ts파일을 만들고 각 콘텐츠 유형에 대한 컬렉션을 내보냅니다.src/content.config.ts import { defineCollection } from 'astro:content';import { z } from 'astro/zod';const blogCollection = defineCollection({schema: z.object({title: z.string(),author: z.string(),date: z.date()})});export const collections = {'blog': blogCollection};콘텐츠 컬렉션에 대해 자세히 알아보세요. -
동적 경로를 사용하여
lang및slug매개변수를 기반으로 콘텐츠를 가져와 렌더링하세요.정적 렌더링 모드에서는
getStaticPaths를 사용하여 각 콘텐츠 항목을 페이지에 매핑합니다.src/pages/[lang]/blog/[...slug].astro ---import { getCollection, render } from 'astro:content';export async function getStaticPaths() {const pages = await getCollection('blog');const paths = pages.map(page => {const [lang, ...slug] = page.id.split('/');return { params: { lang, slug: slug.join('/') || undefined }, props: page };});return paths;}const { lang, slug } = Astro.params;const page = Astro.props;const formattedDate = page.data.date.toLocaleString(lang);const { Content } = await render(page);---<h1>{page.data.title}</h1><p>by {page.data.author} • {formattedDate}</p><Content/>SSR 모드에서 요청된 항목을 직접 가져옵니다.
src/pages/[lang]/blog/[...slug].astro ---import { getEntry, render } from 'astro:content';const { lang, slug } = Astro.params;const page = await getEntry('blog', `${lang}/${slug}`);if (!page) {return Astro.redirect('/404');}const formattedDate = page.data.date.toLocaleString(lang);const { Content, headings } = await render(page);---<h1>{page.data.title}</h1><p>by {page.data.author} • {formattedDate}</p><Content/>동적 라우팅에 대해 자세히 알아보세요.위 예시는 인간이 읽을 수 있는는 문자열을 프런트매터 날짜로 생성하기 위해 내장된
toLocaleString()날짜 형식 지정 방법을 사용합니다. 이렇게 하면 날짜와 시간의 형식이 사용자의 언어와 일치하도록 보장됩니다.
UI 문자열 번역
섹션 제목: “UI 문자열 번역”사이트 주변의 UI 요소에 대한 레이블을 번역하기 위한 용어 사전을 만듭니다. 이를 통해 방문자는 여러분의 사이트를 완전히 자신의 언어로 경험할 수 있습니다.
-
번역 문자열을 저장할
src/i18n/ui.ts파일을 만듭니다.src/i18n/ui.ts export const languages = {en: 'English',fr: 'Français',};export const defaultLang = 'en';export const ui = {en: {'nav.home': 'Home','nav.about': 'About','nav.twitter': 'Twitter',},fr: {'nav.home': 'Accueil','nav.about': 'À propos',},} as const; -
두 개의 도우미 함수를 만듭니다. 하나는 현재 URL을 기반으로 페이지 언어를 감지하고, 다른 하나는
src/i18n/utils.ts파일에서 UI의 다양한 부분에 대한 번역 문자열을 가져옵니다.src/i18n/utils.ts import { ui, defaultLang } from './ui';export function getLangFromUrl(url: URL) {const [, lang] = url.pathname.split('/');if (lang in ui) return lang as keyof typeof ui;return defaultLang;}export function useTranslations(lang: keyof typeof ui) {return function t(key: keyof typeof ui[typeof defaultLang]) {return ui[lang][key] || ui[defaultLang][key];}}1단계에서
nav.twitter문자열이 프랑스어로 번역되지 않았습니다. 고유명사 또는 일반적인 업계 용어와 같은 모든 용어를 번역하고 싶지 않을 수도 있습니다. 키가 번역되지 않은 경우useTranslations도우미는 기본 언어 값을 반환합니다. 이 예시에서는 프랑스어 사용자의 탐색 모음에 “Twitter”도 표시됩니다. -
필요한 경우 도우미를 가져오고 이를 사용하여 현재 언어에 해당하는 UI 문자열을 선택합니다. 예를 들어 nav 컴포넌트는 다음과 같습니다.
src/components/Nav.astro ---import { getLangFromUrl, useTranslations } from '../i18n/utils';const lang = getLangFromUrl(Astro.url);const t = useTranslations(lang);---<ul><li><a href={`/${lang}/home/`}>{t('nav.home')}</a></li><li><a href={`/${lang}/about/`}>{t('nav.about')}</a></li><li><a href="https://twitter.com/astrodotbuild">{t('nav.twitter')}</a></li></ul> -
각 페이지에는 페이지의 언어와 일치하는
<html>요소의lang속성이 있어야 합니다. 이 예시에서 재사용 가능한 레이아웃은 현재 경로에서 언어를 추출합니다.src/layouts/Base.astro ---import { getLangFromUrl } from '../i18n/utils';const lang = getLangFromUrl(Astro.url);---<html lang={lang}><head><meta charset="utf-8" /><link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="viewport" content="width=device-width" /><title>Astro</title></head><body><slot /></body></html> Astro