VitePress i18n 기반 다국어(KO/JA/EN) 블로그 아키텍처 구축기
1줄 요약
VitePress의 내장 locales 설정을 활용하여 한국어(Root), 일본어(/ja/), 영어(/en/)의 독립된 다국어 라우팅을 구축하고, 마크다운 프론트매터 기반 동적 사이드바 및 언어 스위처를 연동한 정적 블로그 아키텍처 실전 가이드.
1. 다국어 디렉토리 구조 및 라우팅 설계
VitePress는 루트 디렉토리 구조를 그대로 URL 패스에 매핑하는 강력한 i18n 라우팅을 지원한다.
uoosnn.github.io/
├── .vitepress/
│ ├── config.mts # 통합 다국어 및 테마 설정
│ └── theme/ # Vue 3 커스텀 레이아웃
├── tech/ # [KO] 기술 트러블슈팅 (Root: /tech/...)
├── blog/ # [KO] 개발 에세이/칼럼
├── ja/ # [JA] 일본어 번역 문서 (/ja/tech/..., /ja/blog/...)
│ ├── tech/
│ └── blog/
├── en/ # [EN] 영어 번역 문서 (/en/tech/..., /en/blog/...)
│ ├── tech/
│ └── blog/
└── index.md # 메인 랜딩 페이지2. .vitepress/config.mts 다국어 locales 설정
각 언어별 네비게이션 바, 사이드바, 검색 인덱스 및 메타데이터를 독립적으로 선언한다.
typescript
import { defineConfig } from 'vitepress';
export default defineConfig({
title: "uoosnn's Tech Log",
locales: {
root: {
label: '한국어',
lang: 'ko-KR',
themeConfig: {
nav: [
{ text: '기술 로그', link: '/tech/' },
{ text: '칼럼', link: '/blog/' },
{ text: '쇼케이스', link: '/projects' }
]
}
},
ja: {
label: '日本語',
lang: 'ja-JP',
link: '/ja/',
themeConfig: {
nav: [
{ text: '技術ログ', link: '/ja/tech/' },
{ text: 'ブログ', link: '/ja/blog/' },
{ text: 'プロジェクト', link: '/ja/projects' }
]
}
},
en: {
label: 'English',
lang: 'en-US',
link: '/en/',
themeConfig: {
nav: [
{ text: 'Tech Notes', link: '/en/tech/' },
{ text: 'Blog', link: '/en/blog/' },
{ text: 'Projects', link: '/en/projects' }
]
}
}
}
});3. 동적 프론트매터 사이드바 생성 (sidebar.ts)
정적 파일명이 한글이거나 언어별로 다를 때 사이드바 타이틀이 깨지는 현상을 방어하기 위해, gray-matter로 각 마크다운의 title 프론트매터를 추출하여 사이드바 트리를 동적 생성한다.
typescript
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
export function getAutoSidebar(dirRelativePath: string) {
const targetDir = path.resolve(__dirname, '..', dirRelativePath);
if (!fs.existsSync(targetDir)) return [];
return fs.readdirSync(targetDir)
.filter(file => file.endsWith('.md') && file !== 'index.md')
.map(file => {
const fullPath = path.join(targetDir, file);
const { data } = matter(fs.readFileSync(fullPath, 'utf-8'));
return {
text: data.title || file.replace('.md', ''),
link: `/${dirRelativePath}/${file.replace('.md', '')}`
};
});
}4. 핵심 체크포인트 (Gotchas)
- 상대 링크 정합성: 다국어 문서 내에서 내부 링크를 작성할 때
/tech/post1이 아닌 현재 로케일 경로(/ja/tech/post1,/en/tech/post1)를 명시하거나 베이스 URL 헬퍼를 사용해야 깨짐을 방지할 수 있다. - 검색 인덱스 분리: 내장 Local Search 사용 시
locales별로 독립된 번역 스트링(placeholder,resetButtonTitle)을 등록해야 사용자 언어에 맞게 검색 UI가 렌더링된다.
게시된 시간: 2026-05-16 12:00:00수정한 시간: 2026-08-15 13:57:00