09. 다국어 지원 (한국어 · English)
1. 개요
한국어와 영어 두 언어로 문서를 제공하고, 상단 메뉴에서 언어를 선택할 수 있게 구성함.
| 방식 | 장단점 |
|---|---|
| 한 페이지에 한국어 · 영어 함께 작성 | 설정은 필요 없지만 글이 두 배로 길어지고 읽기 불편함 |
| 언어별 페이지 분리 (Docusaurus i18n) (선택) | 언어별로 깔끔하게 분리, 언어 전환 시 같은 문서로 이동, 검색엔진 언어 대응 |
적용 범위:
| 영역 | 한국어 | 영어 |
|---|---|---|
| IT · Security · AI 문서 | O | O |
| About | O | O |
| Notes | O | X (한국어 전용) |
2. 구조
| 구분 | 한국어 (기본 언어) | 영어 |
|---|---|---|
| 주소 | wiki.securenomad.kr/... (기존 그대로) | wiki.securenomad.kr/en/... |
| 문서 | docs/ | i18n/en/docusaurus-plugin-content-docs/current/ |
| 일반 페이지 (About) | src/pages/ | i18n/en/docusaurus-plugin-content-pages/ |
| 카테고리 문구 | _category_.json | i18n/en/docusaurus-plugin-content-docs/current.json |
SecureNomad/
├── docs/
│ └── security/xss.md ← 한국어
└── i18n/en/
├── docusaurus-plugin-content-docs/
│ ├── current.json ← 카테고리 문구 번역
│ └── current/
│ └── security/xss.md ← 영어 (같은 경로, 같은 파일 이름)
└── docusaurus-plugin-content-pages/
└── about.md ← About 영어
- 기본 언어인 한국어 주소는 바뀌지 않으므로 기존 검색엔진 등록과 링크가 그대로 유지됨
- 영어 문서는 한국어 문서와 같은 경로, 같은 파일 이름으로 만들어야 서로 연결됨
3. 기본 설정
i18n: {
defaultLocale: 'ko',
locales: ['ko', 'en'],
localeConfigs: {
ko: {label: '한국어', htmlLang: 'ko-KR'},
en: {label: 'English', htmlLang: 'en-US'},
},
},
| 항목 | 의미 |
|---|---|
defaultLocale | 기본 언어. 접두어 없는 주소(/)로 서비스됨 |
locales | 지원 언어 목록. 기본 언어 외에는 /en/ 처럼 접두어가 붙음 |
label | 언어 선택 메뉴에 보이는 이름 |
htmlLang | <html lang> 과 hreflang 값 |
상단 메뉴에 언어 선택 버튼 추가:
{type: 'localeDropdown', position: 'right'},
4. Notes는 한국어만
영어 화면에서는 Notes 메뉴를 숨기고 페이지도 만들지 않음.
Docusaurus는 언어별로 따로 빌드하며, 빌드 중인 언어를 환경 변수 DOCUSAURUS_CURRENT_LOCALE 로 알려 줌.
// 빌드 · 실행 중인 언어 (ko: 한국어, en: 영어)
const currentLocale = process.env.DOCUSAURUS_CURRENT_LOCALE ?? 'ko';
const isKorean = currentLocale === 'ko';
blog: isKorean && { // 영어 빌드에서는 false → 블로그(Notes) 비활성화
path: 'notes',
// ...
},
// Notes는 한국어 화면에서만 표시
...(isKorean ? [{to: '/notes', label: 'Notes', position: 'left'}] : []),
| 결과 | 한국어 | 영어 |
|---|---|---|
| 상단 메뉴 | IT · Security · AI · Notes | IT · Security · AI |
| Notes 페이지 | /notes 생성 | /en/notes 생성 안 됨 |
영어로 번역되지 않은 문서에서 /notes 로 링크하면, 영어 빌드에서 깨진 링크로 판단되어 빌드가 실패할 수 있음. 문서에서 Notes 링크는 가급적 사용하지 않음.
5. 번역 없는 문서 "Korean only" 안내
영어 번역이 없는 문서는 영어 화면에서 한국어 원문이 대신 표시됨 (Docusaurus 기본 동작). 이때 원문 위에 안내 문구를 표시하도록 문서 본문 컴포넌트를 감싸는(wrap) 방식으로 확장함.
import React from 'react';
import Content from '@theme-original/DocItem/Content';
import Admonition from '@theme/Admonition';
import {useDoc} from '@docusaurus/plugin-content-docs/client';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export default function ContentWrapper(props) {
const {metadata} = useDoc();
const {
i18n: {currentLocale, defaultLocale},
} = useDocusaurusContext();
// 번역본이 있으면 source가 '@site/i18n/...', 없으면 원문 '@site/docs/...'
const isFallback =
currentLocale !== defaultLocale && metadata.source.startsWith('@site/docs/');
return (
<>
{isFallback && (
<Admonition type="info" title="Korean only">
This page is available in Korean only. An English version will be added later.
</Admonition>
)}
<Content {...props} />
</>
);
}
동작 원리:
| 상황 | 문서 원본 위치(metadata.source) | 안내 표시 |
|---|---|---|
| 한국어 화면 | @site/docs/... | X (기본 언어) |
| 영어 화면 + 번역 있음 | @site/i18n/en/... | X |
| 영어 화면 + 번역 없음 | @site/docs/... | O |
:::info 테마 확장 (Swizzling)
src/theme/ 아래에 테마 컴포넌트와 같은 경로의 파일을 만들면 기본 컴포넌트를 대체하거나 감쌀 수 있음.
@theme-original/... 로 원래 컴포넌트를 불러와 감싸는 방식(wrap)은 기본 동작을 유지하면서 기능만 추가하므로 업데이트에 비교적 안전함.
:::
6. 메뉴 · 카테고리 문구 번역
번역이 필요한 UI 문구를 JSON 파일로 뽑아 주는 명령:
npm run write-translations -- --locale en
생성 파일과 처리:
| 파일 | 내용 | 처리 |
|---|---|---|
docusaurus-plugin-content-docs/current.json | 카테고리 이름 · 설명 | 유지, 한국어 설명을 영어로 번역 |
docusaurus-theme-classic/navbar.json | 상단 메뉴 문구 | 삭제 (메뉴가 이미 영어) |
docusaurus-theme-classic/footer.json | 하단 저작권 문구 | 삭제 (연도가 고정 값으로 저장되어 매년 갱신되지 않음) |
code.json | 테마 기본 문구 (다음, 이전 등) | 삭제 (테마 기본 영어 문구 사용) |
docusaurus-plugin-content-blog/options.json | 블로그 문구 | 삭제 (영어 Notes 미사용) |
"sidebar.itSidebar.category.Docusaurus Setup.link.generated-index.description": {
"message": "A step-by-step record of building a Docusaurus site on a Windows PC and deploying it to GitHub Pages."
}
번역 파일이 없으면 원래 문구가 그대로 사용됨. 실제로 번역할 문구가 있는 파일만 남기면 관리가 단순해짐.
7. 검색엔진 대응
hreflang 자동 생성
각 페이지에 언어별 버전 정보가 자동으로 들어가 검색엔진이 언어에 맞는 페이지를 보여 줌.
<link rel="alternate" href="https://wiki.securenomad.kr/it/docusaurus-setup/environment" hreflang="ko-KR" />
<link rel="alternate" href="https://wiki.securenomad.kr/en/it/docusaurus-setup/environment" hreflang="en-US" />
<link rel="alternate" href="https://wiki.securenomad.kr/it/docusaurus-setup/environment" hreflang="x-default" />
언어별 사이트맵
| 언어 | 사이트맵 |
|---|---|
| 한국어 | https://wiki.securenomad.kr/sitemap.xml |
| 영어 | https://wiki.securenomad.kr/en/sitemap.xml |
static/robots.txt 에 영어 사이트맵 추가:
User-agent: *
Allow: /
Sitemap: https://wiki.securenomad.kr/sitemap.xml
Sitemap: https://wiki.securenomad.kr/en/sitemap.xml
배포 후 Google Search Console과 네이버 서치어드바이저에 영어 사이트맵도 추가로 제출함.
8. 미리보기와 빌드
| 명령 | 동작 |
|---|---|
npm start | 한국어 화면만 미리보기 |
npm start -- --locale en | 영어 화면만 미리보기 |
npm run build | 한국어(build/) · 영어(build/en/) 모두 빌드 |
개발 서버(npm start)는 한 번에 한 언어만 실행하므로 미리보기 화면에서는 언어 메뉴로 전환되지 않음. 배포된 사이트에서는 정상 전환됨.
빌드는 언어 수만큼 수행되어 시간이 약 두 배로 늘어남.
9. 앞으로 영어 문서 추가하는 방법
- 한국어 문서 작성:
docs/security/xss.md - 같은 경로 · 같은 이름으로 영어 문서 작성:
i18n/en/docusaurus-plugin-content-docs/current/security/xss.md - 새 카테고리(
_category_.json)를 만들었다면npm run write-translations -- --locale en실행 후current.json의 한국어 설명을 영어로 수정 npm run build로 두 언어 모두 빌드 확인 → Commit → Push
영어 문서를 바로 만들지 않아도 됨. 번역이 없으면 영어 화면에서 "Korean only" 안내와 함께 한국어 원문이 표시되므로, 나중에 천천히 추가할 수 있음.
10. 체크리스트
-
i18n설정 (ko 기본, en 추가) 및 언어 선택 메뉴 - Notes 한국어 전용 (영어 메뉴 · 페이지 미생성)
- 번역 없는 문서 "Korean only" 안내
- 기존 문서 영어 번역 (첫 화면, Overview, About, Docusaurus Setup, Troubleshooting)
- 카테고리 설명 번역 (
current.json) - robots.txt에 영어 사이트맵 추가
- 두 언어 빌드 확인
- Search Console · 서치어드바이저에 영어 사이트맵 제출