@intlayer/docs 5.8.0-canary.0 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/intlayer_with_next-i18next.md +2 -2
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +96 -219
- package/blog/ar/react-i18next_vs_react-intl_vs_intlayer.md +88 -129
- package/blog/ar/vue-i18n_vs_intlayer.md +268 -0
- package/blog/de/intlayer_with_next-i18next.md +2 -2
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/de/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/de/vue-i18n_vs_intlayer.md +268 -0
- package/blog/en/intlayer_with_next-i18next.md +2 -2
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +89 -220
- package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +85 -123
- package/blog/en/vue-i18n_vs_intlayer.md +268 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +2 -2
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +85 -218
- package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +80 -130
- package/blog/en-GB/vue-i18n_vs_intlayer.md +258 -0
- package/blog/es/intlayer_with_next-i18next.md +2 -2
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/es/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/es/vue-i18n_vs_intlayer.md +268 -0
- package/blog/fr/intlayer_with_next-i18next.md +2 -2
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
- package/blog/fr/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
- package/blog/fr/vue-i18n_vs_intlayer.md +269 -0
- package/blog/hi/intlayer_with_next-i18next.md +2 -2
- package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +97 -220
- package/blog/hi/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
- package/blog/hi/vue-i18n_vs_intlayer.md +268 -0
- package/blog/it/intlayer_with_next-i18next.md +2 -2
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
- package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
- package/blog/it/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ja/intlayer_with_next-i18next.md +2 -2
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/ja/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/ja/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ko/intlayer_with_next-i18next.md +2 -2
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +95 -217
- package/blog/ko/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
- package/blog/ko/vue-i18n_vs_intlayer.md +268 -0
- package/blog/pt/intlayer_with_next-i18next.md +2 -2
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/pt/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/pt/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ru/intlayer_with_next-i18next.md +2 -2
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +94 -217
- package/blog/ru/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/ru/vue-i18n_vs_intlayer.md +268 -0
- package/blog/zh/intlayer_with_next-i18next.md +2 -2
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/zh/vue-i18n_vs_intlayer.md +269 -0
- package/dist/cjs/generated/blog.entry.cjs +41 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +41 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/docs/ar/formatters.md +417 -31
- package/docs/ar/how_works_intlayer.md +2 -4
- package/docs/ar/interest_of_intlayer.md +7 -10
- package/docs/ar/intlayer_CMS.md +2 -3
- package/docs/ar/intlayer_visual_editor.md +2 -3
- package/docs/ar/intlayer_with_tanstack.md +1 -1
- package/docs/ar/introduction.md +4 -4
- package/docs/de/formatters.md +444 -34
- package/docs/de/introduction.md +2 -2
- package/docs/en/dictionary/enumeration.md +2 -2
- package/docs/en/dictionary/function_fetching.md +2 -2
- package/docs/en/dictionary/get_started.md +2 -2
- package/docs/en/dictionary/translation.md +2 -2
- package/docs/en/formatters.md +383 -15
- package/docs/en/how_works_intlayer.md +2 -4
- package/docs/en/interest_of_intlayer.md +40 -29
- package/docs/en/intlayer_CMS.md +2 -3
- package/docs/en/intlayer_visual_editor.md +2 -3
- package/docs/en/intlayer_with_create_react_app.md +2 -2
- package/docs/en/intlayer_with_express.md +2 -2
- package/docs/en/intlayer_with_tanstack.md +1 -1
- package/docs/en/introduction.md +4 -4
- package/docs/en/packages/express-intlayer/index.md +2 -2
- package/docs/en/packages/intlayer/getConfiguration.md +2 -3
- package/docs/en/packages/intlayer/getEnumeration.md +2 -7
- package/docs/en/packages/intlayer/getHTMLTextDir.md +2 -4
- package/docs/en/packages/intlayer/getLocaleLang.md +2 -4
- package/docs/en/packages/intlayer/getLocaleName.md +2 -3
- package/docs/en/packages/intlayer/getLocalizedUrl.md +2 -8
- package/docs/en/packages/intlayer/getMultilingualUrls.md +2 -7
- package/docs/en/packages/intlayer/getPathWithoutLocale.md +2 -3
- package/docs/en/packages/intlayer/getTranslation.md +2 -4
- package/docs/en/packages/intlayer/index.md +2 -2
- package/docs/en/packages/next-intlayer/index.md +2 -2
- package/docs/en/packages/next-intlayer/t.md +2 -2
- package/docs/en/packages/next-intlayer/useDictionary.md +2 -2
- package/docs/en/packages/next-intlayer/useIntlayer.md +2 -2
- package/docs/en/packages/next-intlayer/useLocale.md +2 -2
- package/docs/en/packages/react-intlayer/index.md +2 -2
- package/docs/en/packages/react-intlayer/t.md +2 -2
- package/docs/en/packages/react-intlayer/useI18n.md +2 -2
- package/docs/en/packages/react-intlayer/useIntlayer.md +2 -2
- package/docs/en/packages/react-intlayer/useLocale.md +2 -2
- package/docs/en/packages/react-scripts-intlayer/index.md +2 -2
- package/docs/en/packages/solid-intlayer/index.md +2 -2
- package/docs/en/packages/vite-intlayer/index.md +2 -2
- package/docs/en-GB/formatters.md +402 -16
- package/docs/en-GB/how_works_intlayer.md +2 -4
- package/docs/en-GB/interest_of_intlayer.md +7 -10
- package/docs/en-GB/intlayer_with_tanstack.md +1 -1
- package/docs/en-GB/introduction.md +2 -2
- package/docs/es/formatters.md +438 -28
- package/docs/es/how_works_intlayer.md +2 -4
- package/docs/es/interest_of_intlayer.md +7 -10
- package/docs/es/intlayer_with_tanstack.md +1 -1
- package/docs/es/introduction.md +2 -2
- package/docs/fr/formatters.md +438 -28
- package/docs/fr/how_works_intlayer.md +2 -4
- package/docs/fr/interest_of_intlayer.md +7 -10
- package/docs/fr/intlayer_with_tanstack.md +1 -1
- package/docs/fr/introduction.md +2 -2
- package/docs/hi/formatters.md +430 -39
- package/docs/hi/how_works_intlayer.md +2 -4
- package/docs/hi/interest_of_intlayer.md +7 -10
- package/docs/hi/intlayer_with_tanstack.md +1 -1
- package/docs/hi/introduction.md +2 -2
- package/docs/it/formatters.md +438 -30
- package/docs/it/how_works_intlayer.md +2 -4
- package/docs/it/interest_of_intlayer.md +7 -10
- package/docs/it/intlayer_with_tanstack.md +1 -1
- package/docs/it/introduction.md +2 -2
- package/docs/ja/formatters.md +435 -47
- package/docs/ja/how_works_intlayer.md +2 -4
- package/docs/ja/interest_of_intlayer.md +7 -10
- package/docs/ja/intlayer_with_tanstack.md +1 -1
- package/docs/ja/introduction.md +2 -2
- package/docs/ko/formatters.md +432 -41
- package/docs/ko/how_works_intlayer.md +2 -4
- package/docs/ko/interest_of_intlayer.md +7 -10
- package/docs/ko/intlayer_with_tanstack.md +1 -1
- package/docs/ko/introduction.md +2 -2
- package/docs/pt/formatters.md +416 -30
- package/docs/pt/how_works_intlayer.md +2 -4
- package/docs/pt/intlayer_with_tanstack.md +1 -1
- package/docs/pt/introduction.md +2 -2
- package/docs/ru/autoFill.md +2 -2
- package/docs/ru/configuration.md +1 -40
- package/docs/ru/formatters.md +438 -28
- package/docs/ru/how_works_intlayer.md +5 -7
- package/docs/ru/index.md +1 -1
- package/docs/ru/interest_of_intlayer.md +8 -11
- package/docs/ru/intlayer_CMS.md +7 -8
- package/docs/ru/intlayer_cli.md +4 -7
- package/docs/ru/intlayer_visual_editor.md +5 -6
- package/docs/ru/intlayer_with_angular.md +1 -1
- package/docs/ru/intlayer_with_create_react_app.md +5 -5
- package/docs/ru/intlayer_with_lynx+react.md +1 -1
- package/docs/ru/intlayer_with_nextjs_15.md +3 -3
- package/docs/ru/intlayer_with_nextjs_page_router.md +2 -2
- package/docs/ru/intlayer_with_nuxt.md +1 -1
- package/docs/ru/intlayer_with_react_native+expo.md +2 -2
- package/docs/ru/intlayer_with_tanstack.md +3 -3
- package/docs/ru/intlayer_with_vite+preact.md +3 -3
- package/docs/ru/intlayer_with_vite+react.md +3 -3
- package/docs/ru/intlayer_with_vite+solid.md +1 -1
- package/docs/ru/intlayer_with_vite+svelte.md +1 -1
- package/docs/ru/intlayer_with_vite+vue.md +2 -2
- package/docs/ru/introduction.md +5 -5
- package/docs/ru/locale_mapper.md +1 -1
- package/docs/ru/packages/@intlayer/api/index.md +2 -2
- package/docs/ru/packages/@intlayer/chokidar/index.md +1 -1
- package/docs/ru/packages/@intlayer/cli/index.md +2 -2
- package/docs/ru/packages/@intlayer/config/index.md +2 -2
- package/docs/ru/packages/@intlayer/core/index.md +2 -2
- package/docs/ru/packages/@intlayer/design-system/index.md +2 -2
- package/docs/ru/packages/@intlayer/dictionary-entry/index.md +2 -2
- package/docs/ru/packages/@intlayer/editor/index.md +1 -1
- package/docs/ru/packages/@intlayer/editor-react/index.md +1 -1
- package/docs/ru/packages/@intlayer/webpack/index.md +1 -1
- package/docs/ru/packages/angular-intlayer/index.md +1 -1
- package/docs/ru/packages/express-intlayer/index.md +3 -3
- package/docs/ru/packages/express-intlayer/t.md +1 -1
- package/docs/ru/packages/intlayer/getEnumeration.md +3 -8
- package/docs/ru/packages/intlayer/getTranslation.md +3 -5
- package/docs/ru/packages/intlayer/getTranslationContent.md +1 -3
- package/docs/ru/packages/intlayer/index.md +3 -3
- package/docs/ru/packages/intlayer-cli/index.md +1 -1
- package/docs/ru/packages/intlayer-editor/index.md +2 -2
- package/docs/ru/packages/lynx-intlayer/index.md +1 -1
- package/docs/ru/packages/next-intlayer/index.md +4 -4
- package/docs/ru/packages/next-intlayer/t.md +4 -4
- package/docs/ru/packages/next-intlayer/useLocale.md +3 -3
- package/docs/ru/packages/nuxt-intlayer/index.md +1 -1
- package/docs/ru/packages/preact-intlayer/index.md +1 -1
- package/docs/ru/packages/react-intlayer/index.md +4 -4
- package/docs/ru/packages/react-intlayer/t.md +4 -4
- package/docs/ru/packages/react-native-intlayer/index.md +1 -1
- package/docs/ru/packages/react-scripts-intlayer/index.md +3 -3
- package/docs/ru/packages/solid-intlayer/index.md +3 -3
- package/docs/ru/packages/svelte-intlayer/index.md +1 -1
- package/docs/ru/packages/vite-intlayer/index.md +3 -3
- package/docs/ru/packages/vue-intlayer/index.md +1 -1
- package/docs/ru/per_locale_file.md +1 -1
- package/docs/ru/roadmap.md +3 -5
- package/docs/ru/vs_code_extension.md +1 -1
- package/docs/zh/formatters.md +446 -38
- package/docs/zh/how_works_intlayer.md +2 -4
- package/docs/zh/interest_of_intlayer.md +7 -10
- package/docs/zh/intlayer_with_tanstack.md +1 -1
- package/docs/zh/introduction.md +2 -2
- package/frequent_questions/ar/domain_routing.md +1 -1
- package/frequent_questions/en/domain_routing.md +1 -1
- package/frequent_questions/en-GB/domain_routing.md +1 -1
- package/frequent_questions/es/domain_routing.md +1 -1
- package/frequent_questions/fr/domain_routing.md +1 -1
- package/frequent_questions/hi/domain_routing.md +1 -1
- package/frequent_questions/it/domain_routing.md +1 -1
- package/frequent_questions/ko/domain_routing.md +1 -1
- package/frequent_questions/pt/domain_routing.md +1 -1
- package/frequent_questions/ru/domain_routing.md +1 -1
- package/frequent_questions/ru/get_locale_cookie.md +4 -4
- package/frequent_questions/ru/static_rendering.md +1 -2
- package/frequent_questions/zh/domain_routing.md +1 -1
- package/package.json +7 -7
- package/src/generated/blog.entry.ts +41 -0
|
@@ -1,194 +1,153 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-01-02
|
|
3
3
|
updatedAt: 2025-06-29
|
|
4
|
-
title: react-
|
|
5
|
-
description: React
|
|
4
|
+
title: react-i18next vs react-intl vs Intlayer
|
|
5
|
+
description: React 앱의 국제화(i18n)를 위해 react-i18next를 next-intl 및 Intlayer와 통합하기
|
|
6
6
|
keywords:
|
|
7
7
|
- next-intl
|
|
8
8
|
- react-i18next
|
|
9
9
|
- Intlayer
|
|
10
10
|
- 국제화
|
|
11
|
-
-
|
|
11
|
+
- 블로그
|
|
12
12
|
- Next.js
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- 자바스크립트
|
|
14
|
+
- 리액트
|
|
15
15
|
slugs:
|
|
16
16
|
- blog
|
|
17
17
|
- react-i18next-vs-react-intl-vs-intlayer
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
#
|
|
20
|
+
# react-Intl VS react-i18next VS intlayer | React 국제화 (i18n)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
이 가이드는 **React**를 위한 세 가지 검증된 i18n 옵션인 **react-intl** (FormatJS), **react-i18next** (i18next), 그리고 **Intlayer**를 비교합니다.
|
|
23
|
+
우리는 **순수 React** 애플리케이션(예: Vite, CRA, SPA)에 중점을 둡니다. Next.js를 사용 중이라면, 전용 Next.js 비교를 참고하세요.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## 1. 소개
|
|
27
|
-
|
|
28
|
-
React 애플리케이션에서 국제화 (i18n)는 여러 방법으로 수행될 수 있습니다. 여기 소개된 세 가지 라이브러리는 서로 다른 디자인 철학, 기능 세트 및 커뮤니티 지원을 가지고 있습니다:
|
|
25
|
+
우리가 평가하는 항목은 다음과 같습니다:
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
- 아키텍처 및 콘텐츠 구성
|
|
28
|
+
- TypeScript 및 안정성
|
|
29
|
+
- 누락된 번역 처리
|
|
30
|
+
- 풍부한 콘텐츠 및 포맷팅 기능
|
|
31
|
+
- 성능 및 로딩 동작
|
|
32
|
+
- 개발자 경험(DX), 도구 및 유지보수
|
|
33
|
+
- SEO/라우팅(프레임워크 의존)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
> **요약**: 세 가지 모두 React 앱을 현지화할 수 있습니다. 만약 **컴포넌트 범위 콘텐츠**, **엄격한 TypeScript 타입**, **빌드 시 누락 키 검사**, **트리 쉐이킹된 사전**, 그리고 내장된 편집 도구(비주얼 에디터/CMS + 선택적 AI 번역)를 원한다면, **Intlayer**가 모듈형 React 코드베이스에 가장 완벽한 선택입니다.
|
|
35
36
|
|
|
36
37
|
---
|
|
37
38
|
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
### 개요
|
|
41
|
-
|
|
42
|
-
[**React-Intl**](https://formatjs.io/docs/react-intl/)은 [FormatJS](https://formatjs.io/) 스위트의 일부입니다. 메시지 포맷팅, 복수형 처리, 날짜/시간 및 숫자 포맷팅을 처리하기 위한 강력한 **API 및 구성 요소** 세트를 제공합니다. React-Intl은 메시지 구문 및 포맷팅을 표준화하는 생태계의 일부이기 때문에 주로 기업 애플리케이션에서 널리 사용됩니다.
|
|
43
|
-
|
|
44
|
-
### 주요 기능
|
|
45
|
-
|
|
46
|
-
- **ICU 메시지 구문**: 메시지 보간, 복수형 처리 등을 위한 포괄적인 구문을 제공합니다.
|
|
47
|
-
- **지역화된 포맷팅**: 로케일에 따라 날짜, 시간, 숫자 및 상대 시간을 포맷하기 위한 내장 유틸리티를 제공합니다.
|
|
48
|
-
- **선언적 컴포넌트**: `<FormattedMessage>`, `<FormattedNumber>`, `<FormattedDate>` 등 JSX에서 매끄럽게 사용할 수 있도록 노출합니다.
|
|
49
|
-
- **풍부한 생태계**: 메시지를 추출, 관리 및 컴파일하기 위한 FormatJS 도구 (예: [babel-plugin-react-intl](https://formatjs.io/docs/tooling/babel-plugin/))와 잘 통합됩니다.
|
|
50
|
-
|
|
51
|
-
### 일반적인 워크플로
|
|
52
|
-
|
|
53
|
-
1. **메시지 카탈로그 정의** (보통 로케일별 JSON 파일).
|
|
54
|
-
2. **앱을 감싸기** `<IntlProvider locale="ko" messages={messages}>`.
|
|
55
|
-
3. **사용하기** `<FormattedMessage id="myMessage" defaultMessage="안녕하세요" />` 또는 `useIntl()` 훅을 사용하여 번역 문자열에 접근합니다.
|
|
56
|
-
|
|
57
|
-
### 장점
|
|
58
|
-
|
|
59
|
-
- 잘 확립되어 있으며 많은 생산 환경에서 사용됩니다.
|
|
60
|
-
- 복수형, 성별, 시간대 등 고급 메시지 포맷을 지원합니다.
|
|
61
|
-
- 메시지 추출 및 컴파일을 위한 강력한 도구 지원을 제공합니다.
|
|
62
|
-
|
|
63
|
-
### 단점
|
|
39
|
+
## 상위 수준 포지셔닝
|
|
64
40
|
|
|
65
|
-
- **ICU
|
|
66
|
-
-
|
|
41
|
+
- **react-intl** - ICU 우선, 표준에 맞는 포맷팅(날짜/숫자/복수형)과 성숙한 API를 제공. 카탈로그는 일반적으로 중앙 집중식이며, 키 안전성과 빌드 시 검증은 주로 사용자가 책임집니다.
|
|
42
|
+
- **react-i18next** - 매우 인기 있고 유연함; 네임스페이스, 탐지기, 다양한 플러그인(ICU, 백엔드 등)을 지원. 강력하지만 프로젝트가 커질수록 설정이 복잡해질 수 있습니다.
|
|
43
|
+
- **Intlayer** - React용 컴포넌트 중심 콘텐츠 모델, **엄격한 TS 타입 지정**, **빌드 시 검사**, **트리 쉐이킹**, 그리고 **비주얼 에디터/CMS** 및 **AI 지원 번역**을 포함. React Router, Vite, CRA 등과 호환됩니다.
|
|
67
44
|
|
|
68
45
|
---
|
|
69
46
|
|
|
70
|
-
##
|
|
47
|
+
## 기능 매트릭스 (React 중심)
|
|
48
|
+
|
|
49
|
+
| 기능 | `react-intlayer` (Intlayer) | `react-i18next` (i18next) | `react-intl` (FormatJS) |
|
|
50
|
+
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
51
|
+
| **컴포넌트 근처 번역** | ✅ 예, 각 컴포넌트와 내용이 함께 위치 | ❌ 아니요 | ❌ 아니요 |
|
|
52
|
+
| **TypeScript 통합** | ✅ 고급, 자동 생성된 엄격한 타입 | ⚠️ 기본; 안전성을 위한 추가 설정 필요 | ✅ 좋음, 하지만 덜 엄격함 |
|
|
53
|
+
| **누락된 번역 감지** | ✅ TypeScript 오류 하이라이트 및 빌드 시 오류/경고 | ⚠️ 대부분 런타임 시 폴백 문자열 | ⚠️ 폴백 문자열 |
|
|
54
|
+
| **리치 콘텐츠 (JSX/Markdown/컴포넌트)** | ✅ 직접 지원 | ⚠️ 제한적 / 인터폴레이션만 | ⚠️ ICU 구문, 실제 JSX 아님 |
|
|
55
|
+
| **AI 기반 번역** | ✅ 예, 여러 AI 제공자를 지원합니다. 자체 API 키를 사용하여 이용 가능하며, 애플리케이션과 콘텐츠 범위의 컨텍스트를 고려합니다. | ❌ 아니요 | ❌ 아니요 |
|
|
56
|
+
| **비주얼 에디터** | ✅ 예, 로컬 비주얼 에디터 + 선택적 CMS 제공; 코드베이스 콘텐츠 외부화 가능; 임베드 가능 | ❌ 아니요 / 외부 현지화 플랫폼을 통해 이용 가능 | ❌ 아니요 / 외부 현지화 플랫폼을 통해 이용 가능 |
|
|
57
|
+
| **로컬라이즈된 라우팅** | ✅ 예, 기본적으로 로컬라이즈된 경로를 지원함 (Next.js 및 Vite와 함께 작동) | ⚠️ 내장 기능 없음, 플러그인(예: `next-i18next`) 또는 커스텀 라우터 설정 필요 | ❌ 없음, 메시지 포맷팅만 지원하며 라우팅은 수동으로 처리해야 함 |
|
|
58
|
+
| **동적 라우트 생성** | ✅ 예 | ⚠️ 플러그인/에코시스템 또는 수동 설정 필요 | ❌ 제공되지 않음 |
|
|
59
|
+
| **복수형 처리** | ✅ 열거형 기반 패턴 | ✅ 구성 가능 (i18next-icu 같은 플러그인 사용) | ✅ (ICU) |
|
|
60
|
+
| **포맷팅 (날짜, 숫자, 통화)** | ✅ 최적화된 포맷터 (내부적으로 Intl 사용) | ⚠️ 플러그인 또는 커스텀 Intl 사용 필요 | ✅ ICU 포맷터 |
|
|
61
|
+
| **콘텐츠 형식** | ✅ .tsx, .ts, .js, .json, .md, .txt, (.yaml 작업 중) | ⚠️ .json | ✅ .json, .js |
|
|
62
|
+
| **ICU 지원** | ⚠️ 작업 중 | ⚠️ 플러그인(i18next-icu)을 통해 | ✅ 예 |
|
|
63
|
+
| **SEO 도우미 (hreflang, 사이트맵)** | ✅ 내장 도구: 사이트맵, robots.txt, 메타데이터 도우미 | ⚠️ 커뮤니티 플러그인/수동 | ❌ 핵심 기능 아님 |
|
|
64
|
+
| **에코시스템 / 커뮤니티** | ⚠️ 작지만 빠르게 성장하고 반응성이 좋음 | ✅ 가장 크고 성숙함 | ✅ 큼 |
|
|
65
|
+
| **서버 사이드 렌더링 및 서버 컴포넌트** | ✅ 예, SSR 및 React 서버 컴포넌트에 최적화됨 | ⚠️ 페이지 단위로 지원되나 자식 서버 컴포넌트에 t-함수를 컴포넌트 트리에 전달해야 함 | ❌ 지원하지 않음, 자식 서버 컴포넌트에 t-함수를 컴포넌트 트리에 전달해야 함 |
|
|
66
|
+
| **트리 쉐이킹 (사용된 콘텐츠만 로드)** | ✅ 예, Babel/SWC 플러그인을 통한 빌드 시 컴포넌트별 적용 | ⚠️ 보통 전체를 로드함 (네임스페이스/코드 분할로 개선 가능) | ⚠️ 보통 전체를 로드함 |
|
|
67
|
+
| **지연 로딩 (Lazy loading)** | ✅ 예, 로케일별 / 사전별 | ✅ 예 (예: 백엔드/네임스페이스 요청 시) | ✅ 예 (로케일 번들 분할) |
|
|
68
|
+
| **사용하지 않는 콘텐츠 정리 (Purge unused content)** | ✅ 예, 빌드 시 사전별 | ❌ 아니요, 수동 네임스페이스 분할을 통해서만 가능 | ❌ 아니요, 선언된 모든 메시지가 번들에 포함됨 |
|
|
69
|
+
| **대규모 프로젝트 관리** | ✅ 모듈화를 장려하며 디자인 시스템에 적합 | ⚠️ 체계적인 파일 관리 필요 | ⚠️ 중앙 카탈로그가 커질 수 있음 |
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
[**React-i18next**](https://react.i18next.com/)는 가장 인기 있는 JavaScript i18n 프레임워크 중 하나인 [i18next](https://www.i18next.com/)의 React 확장입니다. 런타임 번역, 지연 로딩 및 언어 감지를 위한 **광범위한 기능**을 제공하여 매우 다양한 사용 사례에 유연하게 대응할 수 있습니다.
|
|
75
|
-
|
|
76
|
-
### 주요 기능
|
|
77
|
-
|
|
78
|
-
- **유연한 번역 구조**: ICU와 같은 단일 형식에 얽매이지 않습니다. JSON에 번역을 저장하고, 보간, 복수형 처리 등을 사용할 수 있습니다.
|
|
79
|
-
- **동적 언어 전환**: 내장된 언어 감지 플러그인 및 런타임 업데이트 기능을 제공합니다.
|
|
80
|
-
- **중첩 및 구조화된 번역**: JSON 내에서 번역을 쉽게 중첩할 수 있습니다.
|
|
81
|
-
- **광범위한 플러그인 생태계**: 감지(브라우저, 경로, 서브도메인 등), 리소스 로딩, 캐싱 등 많은 기능에 대한 플러그인이 있습니다.
|
|
82
|
-
|
|
83
|
-
### 일반적인 워크플로
|
|
84
|
-
|
|
85
|
-
1. **`i18next` 및 `react-i18next` 설치.**
|
|
86
|
-
2. **i18n 구성**하여 번역(JSON)을 로드하고 언어 감지 또는 기본 언어 설정.
|
|
87
|
-
3. **앱을 감싸기** `I18nextProvider`.
|
|
88
|
-
4. **`useTranslation()` 훅** 또는 `<Trans>` 컴포넌트를 사용하여 번역을 표시합니다.
|
|
71
|
+
---
|
|
89
72
|
|
|
90
|
-
|
|
73
|
+
## 심층 비교
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
- 매우 활발한 커뮤니티와 큰 플러그인 생태계를 가지고 있습니다.
|
|
94
|
-
- 번역의 **동적 로딩**이 쉬움 (예: 서버에서, 필요 시).
|
|
75
|
+
### 1) 아키텍처 및 확장성
|
|
95
76
|
|
|
96
|
-
|
|
77
|
+
- **react-intl / react-i18next**: 대부분의 설정은 언어별로 **중앙 집중식 로케일 폴더**를 유지하며, 때로는 **네임스페이스**(i18next)로 분리됩니다. 초기에는 잘 작동하지만 앱이 커지면서 공유 영역이 됩니다.
|
|
78
|
+
- **Intlayer**: UI와 함께 **컴포넌트별(또는 기능별) 사전**을 **동일 위치에 배치**하는 방식을 권장합니다. 이는 소유권을 명확히 하고, 컴포넌트 복제/이전을 용이하게 하며, 팀 간 키 변경을 줄여줍니다. 사용하지 않는 콘텐츠를 식별하고 제거하기도 쉽습니다.
|
|
97
79
|
|
|
98
|
-
|
|
99
|
-
- 강한 타입의 번역을 선호하는 경우 추가 TypeScript 설정이 필요할 수 있습니다.
|
|
80
|
+
**중요한 이유:** 모듈화된 콘텐츠는 모듈화된 UI를 반영합니다. 대규모 React 코드베이스는 번역이 해당 컴포넌트와 함께 있을 때 더 깔끔하게 유지됩니다.
|
|
100
81
|
|
|
101
82
|
---
|
|
102
83
|
|
|
103
|
-
|
|
84
|
+
### 2) TypeScript 및 안정성
|
|
104
85
|
|
|
105
|
-
|
|
86
|
+
- **react-intl**: 견고한 타입 정의를 제공하지만, **자동 키 타입 지정은 없으며** 안전성 패턴을 직접 적용해야 합니다.
|
|
87
|
+
- **react-i18next**: 훅에 대한 강력한 타입 정의를 제공하며, **엄격한 키 타입 지정은 보통 추가 설정이나 생성기가 필요**합니다.
|
|
88
|
+
- **Intlayer**: 콘텐츠에서 **엄격한 타입을 자동 생성**합니다. IDE 자동완성과 **컴파일 타임 오류**가 런타임 전에 오타와 누락된 키를 잡아냅니다.
|
|
106
89
|
|
|
107
|
-
|
|
90
|
+
**중요한 이유:** 실패를 **왼쪽으로 이동**(빌드/CI 단계로)시켜 프로덕션 문제를 줄이고 개발자 피드백 루프를 가속화합니다.
|
|
108
91
|
|
|
109
|
-
|
|
92
|
+
---
|
|
110
93
|
|
|
111
|
-
|
|
112
|
-
- **내장 라우팅 및 미들웨어**: 로컬 라우팅(e.g., `/ko/about`, `/fr/about`) 및 사용자 로케일 감지를 위한 서버 미들웨어의 선택적 모듈입니다.
|
|
113
|
-
- **자동 생성된 TypeScript 타입**: 자동 완성 및 컴파일 타임 오류 감지를 통해 타입 안전성을 보장합니다.
|
|
114
|
-
- **동적이고 풍부한 번역**: 더 복잡한 사용 사례(예: 링크, 굵은 텍스트, 번역 내 아이콘)를 위해 JSX/TSX를 번역에 포함할 수 있습니다.
|
|
94
|
+
### 3) 누락된 번역 처리
|
|
115
95
|
|
|
116
|
-
|
|
96
|
+
- **react-intl / react-i18next**: 기본적으로 **런타임 폴백**(키 에코 또는 기본 로케일)으로 처리합니다. 린팅/플러그인을 추가할 수 있지만 빌드 시 보장은 없습니다.
|
|
97
|
+
- **Intlayer**: 필수 로케일/키가 누락되면 **빌드 타임 감지**로 경고 또는 오류를 발생시킵니다.
|
|
117
98
|
|
|
118
|
-
|
|
119
|
-
2. **`intlayer.config.ts` 생성**하여 사용 가능한 로케일 및 기본 로케일 정의.
|
|
120
|
-
3. **Intlayer CLI** 또는 플러그인을 사용하여 **콘텐츠 선언 컴파일**.
|
|
121
|
-
4. **앱을 감싸기** `<IntlayerProvider>` 및 `useIntlayer("keyName")`로 콘텐츠를 검색합니다.
|
|
99
|
+
**중요한 이유:** CI가 누락된 문자열을 실패 처리하여 비영어 UI에 “미스터리 영어”가 유출되는 것을 방지합니다.
|
|
122
100
|
|
|
123
|
-
|
|
101
|
+
---
|
|
124
102
|
|
|
125
|
-
|
|
126
|
-
- **풍부한 콘텐츠** 가능 (예: 번역으로 React 노드 전달).
|
|
127
|
-
- 기본으로 **로컬 라이팅**을 지원합니다.
|
|
128
|
-
- 인기 있는 빌드 도구(CRA, Vite)와 통합되어 쉬운 설정을 제공합니다.
|
|
103
|
+
### 4) 풍부한 콘텐츠 및 포맷팅
|
|
129
104
|
|
|
130
|
-
|
|
105
|
+
- **react-intl**: 복수형, 선택형, 날짜/숫자, 메시지 구성에 대해 뛰어난 **ICU** 지원을 제공합니다. JSX를 사용할 수 있지만, 정신 모델은 메시지 중심으로 유지됩니다.
|
|
106
|
+
- **react-i18next**: 유연한 보간법과 요소/컴포넌트를 포함할 수 있는 **`<Trans>`**를 지원하며, ICU는 플러그인을 통해 사용할 수 있습니다.
|
|
107
|
+
- **Intlayer**: 콘텐츠 파일에 **리치 노드**(JSX/Markdown/컴포넌트)와 **메타데이터**를 포함할 수 있습니다. 포맷팅은 내부적으로 Intl을 사용하며, 복수형 패턴이 사용하기 편리합니다.
|
|
131
108
|
|
|
132
|
-
|
|
133
|
-
- "컴포넌트 수준 콘텐츠 선언" 접근 방식에 더 중점을 두므로 전형적인 .json 카탈로그에서 옮기는 것이 필요할 수 있습니다.
|
|
134
|
-
- 더 확립된 라이브러리들에 비해 생태계와 커뮤니티가 작습니다.
|
|
109
|
+
**중요한 이유:** 복잡한 UI 텍스트(링크, 굵은 부분, 인라인 컴포넌트 등)는 라이브러리가 React 노드를 깔끔하게 수용할 때 더 쉽게 처리할 수 있습니다.
|
|
135
110
|
|
|
136
111
|
---
|
|
137
112
|
|
|
138
|
-
|
|
113
|
+
### 5) 성능 및 로딩 동작
|
|
114
|
+
|
|
115
|
+
- **react-intl / react-i18next**: 일반적으로 **카탈로그 분할**과 **지연 로딩**을 수동으로 관리합니다(네임스페이스/동적 임포트). 효과적이지만 규율이 필요합니다.
|
|
116
|
+
- **Intlayer**: 사용하지 않는 사전을 **트리 쉐이킹**하고 **사전별/로케일별 지연 로딩**을 기본적으로 지원합니다.
|
|
139
117
|
|
|
140
|
-
|
|
141
|
-
| ---------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
142
|
-
| **주요 사용 사례** | 문자열 기반 번역, 날짜/숫자 포맷팅, ICU 메시지 구문 | 동적인 전환, 중첩, 플러그인 생태계를 갖춘 완전한 기능을 갖춘 i18n | 선언적 콘텐츠, 로컬 라우팅 및 선택적 서버 미들웨어에 중점을 둔 타입 안전 번역 |
|
|
143
|
-
| **접근 방식** | `<IntlProvider>` 및 FormatJS 메시지 컴포넌트 사용 | `I18nextProvider` 및 `useTranslation()` 훅 사용 | `<IntlayerProvider>` 및 `useIntlayer()` 훅과 콘텐츠 선언 사용 |
|
|
144
|
-
| **지역화 형식** | ICU 기반 문자열 (JSON 또는 JavaScript 카탈로그) | JSON 리소스 파일 (또는 사용자 정의 로더). ICU 형식은 i18next 플러그인을 통해 선택적으로 사용 가능 | `.content.[ts/js/tsx]` 또는 JSON 선언; 문자열 또는 React 컴포넌트 포함 가능 |
|
|
145
|
-
| **라우팅** | 외부에서 처리 (내장된 로컬 라우팅 없음) | i18next 플러그인을 통한 외부 처리 (경로, 서브도메인 감지 등) | 내장된 로컬 라우팅 지원 (예: `/ko/about`, `/fr/about`), SSR/Vite를 위한 선택적 서버 미들웨어 제공 |
|
|
146
|
-
| **TypeScript 지원** | 좋음 (공식 패키지에 대한 타입 정의) | 좋음, 그러나 강력하게 타입이 체크된 번역을 원할 경우 추가 구성이 필요 | 우수함 (콘텐츠 키 및 번역에 대해 자동 생성된 타입 정의) |
|
|
147
|
-
| **복수형 및 포맷팅** | 고급: 내장된 날짜/시간/숫자 포맷팅, 복수형/성별 지원 | 구성 가능한 복수형 처리. 날짜/시간 포맷팅은 일반적으로 외부 라이브러리 또는 i18next 플러그인을 통해 수행 | 표준 JavaScript Intl에 의존 가능하거나 콘텐츠에 로직 내장. FormatJS만큼 전문적이지는 않지만 일반적인 경우를 처리. |
|
|
148
|
-
| **커뮤니티 및 생태계** | 대규모, FormatJS 생태계의 일부 | 매우 대규모, 매우 활성화, 많은 플러그인(감지, 캐싱, 프레임워크 등) | 작지만 성장 중; 오픈 소스, 현대적 접근 |
|
|
149
|
-
| **학습 곡선** | 보통 (ICU 메시지 구문 및 FormatJS 규칙 학습 필요) | 낮음에서 보통 (직관적인 사용법, 그러나 고급 구성은 다소 번거로울 수 있음) | 보통 (콘텐츠 선언의 개념 및 특수 빌드 단계) |
|
|
118
|
+
**중요한 이유:** 더 작은 번들과 사용하지 않는 문자열 감소는 시작 및 탐색 성능을 향상시킵니다.
|
|
150
119
|
|
|
151
120
|
---
|
|
152
121
|
|
|
153
|
-
|
|
122
|
+
### 6) 개발자 경험(DX), 도구 및 유지보수
|
|
154
123
|
|
|
155
|
-
|
|
124
|
+
- **react-intl / react-i18next**: 광범위한 커뮤니티 생태계; 편집 워크플로우를 위해 일반적으로 외부 현지화 플랫폼을 채택합니다.
|
|
125
|
+
- **Intlayer**: **무료 비주얼 에디터**와 **선택적 CMS**(콘텐츠를 Git에 보관하거나 외부화 가능)를 제공합니다. 또한 콘텐츠 작성용 **VSCode 확장**과 자체 제공자 키를 사용하는 **AI 지원 번역** 기능도 제공합니다.
|
|
156
126
|
|
|
157
|
-
|
|
158
|
-
- 번역에 대한 더 “**표준 기반**” 접근을 선호합니다.
|
|
159
|
-
- 로컬 라우팅 또는 강타입 번역 키가 필요하지 않습니다.
|
|
127
|
+
**중요한 이유:** 내장된 도구는 개발자와 콘텐츠 작성자 간의 작업 흐름을 단축시켜 - 접착 코드가 줄고, 벤더 의존성이 감소합니다.
|
|
160
128
|
|
|
161
|
-
|
|
129
|
+
---
|
|
162
130
|
|
|
163
|
-
|
|
164
|
-
- URL, 쿠키, 로컬 스토리지 등을 통해 **플러그인 기반** 언어 감지를 원합니다.
|
|
165
|
-
- 최대 생태계, 다양한 프레임워크(Next.js, React Native 등)과의 많은 기존 통합이 필요합니다.
|
|
131
|
+
## 언제 어떤 것을 선택해야 할까요?
|
|
166
132
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
- **내장된 로컬 라우팅**이 필요하거나 SSR 또는 Vite 설정에 쉽게 통합하고 싶습니다.
|
|
171
|
-
- 현대적인 접근을 원하거나 **콘텐츠 관리** (i18n) 및 **라우팅**을 타입 안전하게 다루는 단일 라이브러리를 원합니다.
|
|
133
|
+
- **react-intl**을 선택하세요, 만약 **ICU 우선** 메시지 포맷팅과 직관적이고 표준에 맞는 API를 원하며, 팀이 카탈로그와 안전성 검사를 수동으로 관리하는 데 익숙하다면.
|
|
134
|
+
- **react-i18next**를 선택하세요, 만약 **i18next 생태계의 폭넓은 기능**(탐지기, 백엔드, ICU 플러그인, 통합 등)이 필요하고, 유연성을 얻기 위해 더 많은 설정을 감수할 수 있다면.
|
|
135
|
+
- **Intlayer를 선택하세요** 만약 **컴포넌트 범위의 콘텐츠**, **엄격한 TypeScript**, **빌드 시 보장**, **트리 쉐이킹**, 그리고 **포함된 편집 도구**를 중요하게 생각한다면 - 특히 **크고 모듈화된** React 앱에 적합합니다.
|
|
172
136
|
|
|
173
137
|
---
|
|
174
138
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
각 라이브러리는 React 애플리케이션의 국제화를 위한 강력한 솔루션을 제공합니다:
|
|
178
|
-
|
|
179
|
-
- **React-Intl**은 메시지 포맷팅에서 뛰어나며 ICU 메시지 구문에 중점을 둔 기업 솔루션에 인기있는 선택입니다.
|
|
180
|
-
- **React-i18next**는 고급 또는 동적 i18n 요구 사항을 위한 매우 유연하고 플러그인 주도의 환경을 제공합니다.
|
|
181
|
-
- **Intlayer**는 **현대적이고 강한 타입** 접근 방식을 제공하여 콘텐츠 선언, 고급 로컬 라우팅 및 플러그인 기반(CRA, Vite) 통합을 결합합니다.
|
|
139
|
+
## 실용적인 마이그레이션 노트 (react-intl / react-i18next → Intlayer)
|
|
182
140
|
|
|
183
|
-
|
|
141
|
+
- **점진적으로 마이그레이션하세요**: 한 기능 또는 라우트부터 시작하고, 전환 기간 동안 기존 카탈로그를 병행 유지하세요.
|
|
142
|
+
- **컴포넌트별 사전 사용을 채택하세요**: 콘텐츠를 컴포넌트와 함께 배치하여 결합도를 줄이세요.
|
|
143
|
+
- **엄격한 검사 활성화**: 빌드 시 오류가 누락된 키/로케일을 CI 초기에 드러내도록 하세요.
|
|
144
|
+
- **번들 크기 측정**: 사용하지 않는 문자열이 제거되면서 크기 감소를 기대하세요.
|
|
184
145
|
|
|
185
146
|
---
|
|
186
147
|
|
|
187
|
-
|
|
148
|
+
## 결론
|
|
188
149
|
|
|
189
|
-
|
|
190
|
-
- [React-i18next 문서](https://react.i18next.com/)
|
|
191
|
-
- [Intlayer + CRA 시작 가이드](#) (귀하의 문서에서)
|
|
192
|
-
- [Intlayer + Vite & React 시작 가이드](#) (귀하의 문서에서)
|
|
150
|
+
세 가지 라이브러리 모두 React를 효과적으로 현지화합니다. 차별점은 **안전하고 확장 가능한** 환경을 구축하기 위해 얼마나 많은 **인프라**를 만들어야 하는가에 있습니다:
|
|
193
151
|
|
|
194
|
-
|
|
152
|
+
- **Intlayer**는 **모듈화된 콘텐츠**, **엄격한 TS 타입 검사**, **빌드 시 안전성**, **트리 쉐이킹된 번들**, 그리고 **편집 도구**를 기본으로 제공하며, 이는 번거로운 작업이 아닙니다.
|
|
153
|
+
- 팀이 다국어, 컴포넌트 중심의 React 앱에서 **유지보수성과 속도**를 중요시한다면, Intlayer는 오늘날 가장 **완벽한** 개발자 및 콘텐츠 워크플로우를 제공합니다.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2024-08-11
|
|
3
|
+
updatedAt: 2025-08-23
|
|
4
|
+
title: vue-i18n 대 Intlayer
|
|
5
|
+
description: Vue/Nuxt 앱에서 국제화(i18n)를 위해 vue-i18n과 Intlayer를 비교
|
|
6
|
+
keywords:
|
|
7
|
+
- vue-i18n
|
|
8
|
+
- Intlayer
|
|
9
|
+
- 국제화
|
|
10
|
+
- i18n
|
|
11
|
+
- 블로그
|
|
12
|
+
- Vue
|
|
13
|
+
- Nuxt
|
|
14
|
+
- 자바스크립트
|
|
15
|
+
slugs:
|
|
16
|
+
- blog
|
|
17
|
+
- vue-i18n-vs-intlayer
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# vue-i18n 대 Intlayer | Vue 국제화(i18n)
|
|
21
|
+
|
|
22
|
+
이 가이드는 **Vue 3** (및 **Nuxt**)용으로 인기 있는 두 가지 i18n 옵션인 **vue-i18n**과 **Intlayer**를 비교합니다.
|
|
23
|
+
우리는 최신 Vue 도구(Vite, Composition API)에 중점을 두고 다음을 평가합니다:
|
|
24
|
+
|
|
25
|
+
1. **아키텍처 및 콘텐츠 구성**
|
|
26
|
+
2. **TypeScript 및 안전성**
|
|
27
|
+
3. **번역 누락 처리**
|
|
28
|
+
4. **라우팅 및 URL 전략**
|
|
29
|
+
5. **성능 및 로딩 동작**
|
|
30
|
+
6. **개발자 경험(DX), 도구 및 유지보수**
|
|
31
|
+
7. **SEO 및 대규모 프로젝트 확장성**
|
|
32
|
+
|
|
33
|
+
> **요약**: 두 솔루션 모두 Vue 앱을 현지화할 수 있습니다. 만약 **컴포넌트 범위 콘텐츠**, **엄격한 TypeScript 타입**, **빌드 시 누락 키 검사**, **트리 쉐이킹된 사전**, 그리고 **기본 제공 라우터/SEO 도우미**와 더불어 **비주얼 에디터 및 AI 번역**을 원한다면, **Intlayer**가 더 완전하고 현대적인 선택입니다.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 상위 수준 포지셔닝
|
|
38
|
+
|
|
39
|
+
- **vue-i18n** - Vue의 사실상 표준 i18n 라이브러리입니다. 유연한 메시지 포맷팅(ICU 스타일), 로컬 메시지를 위한 SFC `<i18n>` 블록, 그리고 방대한 생태계를 갖추고 있습니다. 안전성과 대규모 유지보수는 주로 사용자의 몫입니다.
|
|
40
|
+
- **Intlayer** - 엄격한 TS 타이핑, 빌드 타임 검사, 트리 쉐이킹, 라우터 및 SEO 도우미, 선택적 비주얼 에디터/CMS, AI 지원 번역 기능을 갖춘 Vue/Vite/Nuxt용 컴포넌트 중심 콘텐츠 모델입니다.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 나란히 기능 비교 (Vue 중심)
|
|
45
|
+
|
|
46
|
+
| 기능 | **Intlayer** | **vue-i18n** |
|
|
47
|
+
| ------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
48
|
+
| **컴포넌트 근처 번역** | ✅ 예, 컴포넌트별로 콘텐츠가 함께 위치 (예: `MyComp.content.ts`) | ✅ 예, SFC `<i18n>` 블록을 통해 (선택 사항) |
|
|
49
|
+
| **TypeScript 통합** | ✅ 고급, 자동 생성된 **엄격한** 타입 및 키 자동완성 | ✅ 좋은 타입 정의; **엄격한 키 안전성은 추가 설정/규율 필요** |
|
|
50
|
+
| **번역 누락 감지** | ✅ **빌드 시** 경고/오류 및 TS 노출 | ⚠️ 런타임 대체/경고 |
|
|
51
|
+
| **풍부한 콘텐츠 (컴포넌트/마크다운)** | ✅ 풍부한 노드 및 마크다운 콘텐츠 파일에 대한 직접 지원 | ⚠️ 제한적 지원 (`<i18n-t>`를 통한 컴포넌트, 외부 플러그인을 통한 마크다운) |
|
|
52
|
+
| **AI 기반 번역** | ✅ 자체 AI 제공자 키를 사용하는 내장 워크플로우 | ❌ 내장되어 있지 않음 |
|
|
53
|
+
| **비주얼 에디터 / CMS** | ✅ 무료 비주얼 에디터 및 선택적 CMS | ❌ 내장되어 있지 않음 (외부 플랫폼 사용) |
|
|
54
|
+
| **지역화된 라우팅** | ✅ Vue Router/Nuxt용 로컬라이즈된 경로, URL 및 `hreflang` 생성을 위한 헬퍼 제공 | ⚠️ 핵심 기능 아님 (Nuxt i18n 또는 커스텀 Vue Router 설정 사용) |
|
|
55
|
+
| **동적 라우트 생성** | ✅ 지원 | ❌ 제공되지 않음 (Nuxt i18n에서 제공) |
|
|
56
|
+
| **복수형 처리 및 포맷팅** | ✅ 열거형 패턴; Intl 기반 포맷터 | ✅ ICU 스타일 메시지; Intl 포맷터 |
|
|
57
|
+
| **콘텐츠 형식** | ✅ `.ts`, `.js`, `.json`, `.md`, `.txt` (YAML 작업 중) | ✅ `.json`, `.js` (SFC `<i18n>` 블록 포함) |
|
|
58
|
+
| **ICU 지원** | ⚠️ 작업 중 | ✅ 예 |
|
|
59
|
+
| **SEO 도우미 (사이트맵, 로봇, 메타데이터)** | ✅ 내장 도우미 (프레임워크 독립적) | ❌ 핵심 아님 (Nuxt i18n/커뮤니티) |
|
|
60
|
+
| **SSR/SSG** | ✅ Vue SSR 및 Nuxt와 함께 작동; 정적 렌더링을 차단하지 않음 | ✅ Vue SSR/Nuxt와 함께 작동 |
|
|
61
|
+
| **트리 쉐이킹 (사용된 콘텐츠만 포함)** | ✅ 빌드 시 컴포넌트별 적용 | ⚠️ 부분적 지원; 수동 코드 분할/비동기 메시지 필요 |
|
|
62
|
+
| **지연 로딩** | ✅ 로케일별 / 사전별 적용 | ✅ 비동기 로케일 메시지 지원 |
|
|
63
|
+
| **사용하지 않는 콘텐츠 정리** | ✅ 예 (빌드 시) | ❌ 내장되어 있지 않음 |
|
|
64
|
+
| **대규모 프로젝트 유지보수성** | ✅ 모듈화되고 디자인 시스템 친화적인 구조 권장 | ✅ 가능하지만 강력한 파일/네임스페이스 규율 필요 |
|
|
65
|
+
| **생태계 / 커뮤니티** | ⚠️ 작지만 빠르게 성장 중 | ✅ Vue 생태계 내 크고 성숙함 |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 심층 비교
|
|
70
|
+
|
|
71
|
+
### 1) 아키텍처 및 확장성
|
|
72
|
+
|
|
73
|
+
- **vue-i18n**: 일반적인 설정은 로케일별로 **중앙 집중식 카탈로그**를 사용하며(선택적으로 파일/네임스페이스로 분할 가능), SFC `<i18n>` 블록은 로컬 메시지를 허용하지만 프로젝트가 커짐에 따라 팀들은 종종 공유 카탈로그로 되돌아갑니다.
|
|
74
|
+
- **Intlayer**: 각 컴포넌트 옆에 저장되는 **컴포넌트별 사전**을 권장합니다. 이는 팀 간 충돌을 줄이고, 콘텐츠를 쉽게 찾을 수 있게 하며, 자연스럽게 사용되지 않는 키의 누락이나 분산을 제한합니다.
|
|
75
|
+
|
|
76
|
+
**중요한 이유:** 대규모 Vue 앱이나 디자인 시스템에서는 **모듈화된 콘텐츠**가 단일 카탈로그보다 더 잘 확장됩니다.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### 2) TypeScript 및 안정성
|
|
81
|
+
|
|
82
|
+
- **vue-i18n**: 좋은 TS 지원을 제공하지만, **엄격한 키 타입 지정**은 일반적으로 사용자 정의 스키마/제네릭 및 신중한 규칙이 필요합니다.
|
|
83
|
+
- **Intlayer**: 콘텐츠에서 **엄격한 타입을 생성**하여 **IDE 자동완성**과 오타/누락 키에 대한 **컴파일 타임 오류**를 제공합니다.
|
|
84
|
+
|
|
85
|
+
**중요한 이유:** 강력한 타입 검사는 **런타임 이전에** 문제를 잡아냅니다.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### 3) 누락된 번역 처리
|
|
90
|
+
|
|
91
|
+
- **vue-i18n**: **런타임** 경고/대체 처리(예: 대체 로케일 또는 키 사용).
|
|
92
|
+
- **Intlayer**: 로케일과 키 전반에 걸친 경고/오류를 포함한 **빌드 타임** 감지.
|
|
93
|
+
|
|
94
|
+
**중요한 이유:** 빌드 타임 강제 적용으로 프로덕션 UI를 깔끔하고 일관되게 유지합니다.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### 4) 라우팅 및 URL 전략 (Vue Router/Nuxt)
|
|
99
|
+
|
|
100
|
+
- **둘 다** 지역화된 라우트와 함께 작동할 수 있습니다.
|
|
101
|
+
- **Intlayer**는 **지역화된 경로 생성**, **로케일 접두사 관리**, 그리고 SEO를 위한 **`<link rel="alternate" hreflang>`** 발행을 돕는 헬퍼를 제공합니다. Nuxt와 함께 사용 시, 프레임워크의 라우팅을 보완합니다.
|
|
102
|
+
|
|
103
|
+
**중요한 이유:** 맞춤형 연결 계층이 줄어들고, 여러 로케일에 걸쳐 **더 깔끔한 SEO**를 구현할 수 있습니다.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### 5) 성능 및 로딩 동작
|
|
108
|
+
|
|
109
|
+
- **vue-i18n**: 비동기 로케일 메시지를 지원하며, 과도한 번들링 방지는 사용자의 책임입니다(카탈로그를 신중히 분할해야 함).
|
|
110
|
+
- **Intlayer**: 빌드 시 **트리 쉐이킹**을 수행하고, 사전/로케일별로 **지연 로딩**합니다. 사용하지 않는 콘텐츠는 포함되지 않습니다.
|
|
111
|
+
|
|
112
|
+
**중요한 이유:** 더 작은 번들과 다중 로케일 Vue 앱의 더 빠른 시작 속도를 제공합니다.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### 6) 개발자 경험 및 도구
|
|
117
|
+
|
|
118
|
+
- **vue-i18n**: 성숙한 문서와 커뮤니티를 갖추고 있으며, 일반적으로 편집 워크플로우를 위해 **외부 현지화 플랫폼**에 의존합니다.
|
|
119
|
+
- **Intlayer**: **무료 비주얼 에디터**, 선택적 **CMS**(Git 친화적이거나 외부화 가능), **VSCode 확장**, **CLI/CI** 유틸리티, 그리고 사용자의 제공자 키를 활용한 **AI 지원 번역**을 제공합니다.
|
|
120
|
+
|
|
121
|
+
**중요한 이유:** 운영 비용 절감과 개발-콘텐츠 주기의 단축.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### 7) SEO, SSR 및 SSG
|
|
126
|
+
|
|
127
|
+
- **두 솔루션 모두** Vue SSR과 Nuxt와 함께 작동합니다.
|
|
128
|
+
- **Intlayer**: 프레임워크에 구애받지 않는 **SEO 도우미**(사이트맵/메타데이터/`hreflang`)를 추가하여 Vue/Nuxt 빌드와 원활하게 작동합니다.
|
|
129
|
+
|
|
130
|
+
**중요한 이유:** 맞춤형 연결 없이 국제 SEO 구현 가능.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 왜 Intlayer인가? (문제점 및 접근법)
|
|
135
|
+
|
|
136
|
+
대부분의 i18n 스택(예: **vue-i18n**)은 **중앙 집중식 카탈로그**에서 시작합니다:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
.
|
|
140
|
+
├── locales
|
|
141
|
+
│ ├── en.json
|
|
142
|
+
│ ├── es.json
|
|
143
|
+
│ └── fr.json
|
|
144
|
+
└── src
|
|
145
|
+
└── components
|
|
146
|
+
└── MyComponent.vue
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
또는 로케일별 폴더 구조:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
.
|
|
153
|
+
├── locales
|
|
154
|
+
│ ├── en
|
|
155
|
+
│ │ ├── footer.json
|
|
156
|
+
│ │ └── navbar.json
|
|
157
|
+
│ ├── fr
|
|
158
|
+
│ │ ├── footer.json
|
|
159
|
+
│ │ └── navbar.json
|
|
160
|
+
│ └── es
|
|
161
|
+
│ ├── footer.json
|
|
162
|
+
│ └── navbar.json
|
|
163
|
+
└── src
|
|
164
|
+
└── components
|
|
165
|
+
└── MyComponent.vue
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
이 방식은 앱이 커질수록 개발 속도를 저하시킵니다:
|
|
169
|
+
|
|
170
|
+
1. **새 컴포넌트의 경우** 원격 카탈로그를 생성/편집하고, 네임스페이스를 연결하며, 번역 작업을 수행합니다 (종종 AI 도구에서 복사/붙여넣기 수동 작업 포함).
|
|
171
|
+
2. **컴포넌트를 변경할 때** 공유 키를 찾아 번역하고, 로케일을 동기화하며, 사용하지 않는 키를 제거하고, JSON 구조를 맞춥니다.
|
|
172
|
+
|
|
173
|
+
**Intlayer**는 콘텐츠를 **컴포넌트별로 구분**하고, CSS, 스토리, 테스트, 문서와 같이 **코드 옆에 보관**합니다:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
.
|
|
177
|
+
└── components
|
|
178
|
+
└── MyComponent
|
|
179
|
+
├── MyComponent.content.ts
|
|
180
|
+
└── MyComponent.vue
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**콘텐츠 선언** (컴포넌트별):
|
|
184
|
+
|
|
185
|
+
```ts fileName="./components/MyComponent/MyComponent.content.ts"
|
|
186
|
+
import { t, type Dictionary } from "intlayer";
|
|
187
|
+
|
|
188
|
+
const componentExampleContent = {
|
|
189
|
+
key: "component-example",
|
|
190
|
+
content: {
|
|
191
|
+
greeting: t({
|
|
192
|
+
en: "Hello World",
|
|
193
|
+
es: "Hola Mundo",
|
|
194
|
+
fr: "Bonjour le monde",
|
|
195
|
+
}),
|
|
196
|
+
},
|
|
197
|
+
} satisfies Dictionary;
|
|
198
|
+
|
|
199
|
+
export default componentExampleContent;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Vue에서 사용법** (Composition API):
|
|
203
|
+
|
|
204
|
+
```vue fileName="./components/MyComponent/MyComponent.vue"
|
|
205
|
+
<script setup lang="ts">
|
|
206
|
+
import { useIntlayer } from "vue-intlayer"; // Vue 통합
|
|
207
|
+
const { greeting } = useIntlayer("component-example");
|
|
208
|
+
</script>
|
|
209
|
+
|
|
210
|
+
<template>
|
|
211
|
+
<span>{{ greeting }}</span>
|
|
212
|
+
</template>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
이 접근 방식:
|
|
216
|
+
|
|
217
|
+
- **개발 속도 향상** (한 번 선언; IDE/AI 자동완성 지원).
|
|
218
|
+
- **코드베이스 정리** (1 컴포넌트 = 1 사전).
|
|
219
|
+
- **복제/마이그레이션 용이** (컴포넌트와 콘텐츠를 함께 복사).
|
|
220
|
+
- **죽은 키 방지** (사용하지 않는 컴포넌트는 콘텐츠를 가져오지 않음).
|
|
221
|
+
- **로딩 최적화** (지연 로드된 컴포넌트가 자신의 콘텐츠를 함께 가져옴).
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Intlayer의 추가 기능 (Vue 관련)
|
|
226
|
+
|
|
227
|
+
- **크로스 프레임워크 지원**: Vue, Nuxt, Vite, React, Express 등과 함께 작동.
|
|
228
|
+
- **자바스크립트 기반 콘텐츠 관리**: 코드 내에서 완전한 유연성으로 선언.
|
|
229
|
+
- **로케일별 선언 파일**: 모든 로케일을 시드(seed)하고 도구가 나머지를 생성하도록 합니다.
|
|
230
|
+
- **타입 안전 환경**: 자동 완성을 지원하는 강력한 TS 구성.
|
|
231
|
+
- **간소화된 콘텐츠 조회**: 사전을 위한 모든 콘텐츠를 가져오는 단일 훅/컴포저블.
|
|
232
|
+
- **체계적인 코드베이스**: 1 컴포넌트 = 동일 폴더 내 1 사전.
|
|
233
|
+
- **향상된 라우팅**: **Vue Router/Nuxt** 로케일 경로 및 메타데이터를 위한 헬퍼.
|
|
234
|
+
- **마크다운 지원**: 로케일별 원격/로컬 마크다운 가져오기; 프런트매터를 코드에 노출.
|
|
235
|
+
- **무료 비주얼 에디터 및 선택적 CMS**: 유료 로컬라이제이션 플랫폼 없이 작성 가능; Git 친화적 동기화.
|
|
236
|
+
- **트리 쉐이커블 콘텐츠**: 사용된 것만 배포; 지연 로딩 지원.
|
|
237
|
+
- **정적 렌더링 친화적**: SSG를 차단하지 않음.
|
|
238
|
+
- **AI 기반 번역**: 자체 AI 제공자/API 키를 사용하여 231개 언어로 번역합니다.
|
|
239
|
+
- **MCP 서버 및 VSCode 확장**: IDE 내에서 i18n 워크플로우와 작성 작업을 자동화합니다.
|
|
240
|
+
- **상호 운용성**: 필요에 따라 **vue-i18n**, **react-i18next**, **react-intl**과 연동합니다.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 언제 어떤 것을 선택해야 할까요?
|
|
245
|
+
|
|
246
|
+
- **vue-i18n을 선택하세요**: 표준 Vue 방식을 원하고, 카탈로그/네임스페이스 관리를 직접 할 수 있으며, 앱이 **소규모에서 중간 규모**이거나 이미 Nuxt i18n을 사용 중인 경우.
|
|
247
|
+
- **Intlayer를 선택하세요**: **컴포넌트 범위 콘텐츠**, **엄격한 TypeScript**, **빌드 타임 보장**, **트리 쉐이킹**, 그리고 **포함된 라우팅/SEO/에디터 도구**를 중요시하며, 특히 **대규모 모듈형 Vue/Nuxt 코드베이스**에 적합합니다.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 실용적인 마이그레이션 노트 (vue-i18n → Intlayer)
|
|
252
|
+
|
|
253
|
+
- **기능별로 시작하기**: 한 번에 하나의 라우트/뷰/컴포넌트를 로컬 Intlayer 사전으로 옮기세요.
|
|
254
|
+
- **마이그레이션 중 브리지 유지**: vue-i18n 카탈로그를 병행 유지하며 점진적으로 조회를 대체하세요.
|
|
255
|
+
- **엄격한 검사 활성화**: 빌드 시 누락된 키/로케일을 조기에 감지하도록 하세요.
|
|
256
|
+
- **라우터/SEO 도우미 채택**: 로케일 감지와 `hreflang` 태그를 표준화하세요.
|
|
257
|
+
- **번들 크기 측정**: 사용하지 않는 콘텐츠가 제외되면서 **번들 크기 감소**를 기대하세요.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 결론
|
|
262
|
+
|
|
263
|
+
**vue-i18n**과 **Intlayer** 모두 Vue 앱을 잘 현지화합니다. 차이점은 견고하고 확장 가능한 설정을 위해 **얼마나 많이 직접 구축해야 하는가**에 있습니다:
|
|
264
|
+
|
|
265
|
+
- **Intlayer**는 **모듈화된 콘텐츠**, **엄격한 TS**, **빌드 시 안전성**, **트리 쉐이킹된 번들**, 그리고 **라우터/SEO/에디터 도구**를 **기본 제공**합니다.
|
|
266
|
+
- 팀이 다중 로케일, 컴포넌트 기반 Vue/Nuxt 앱에서 **유지보수성과 속도**를 우선시한다면, Intlayer는 오늘날 **가장 완벽한** 경험을 제공합니다.
|
|
267
|
+
|
|
268
|
+
자세한 내용은 ['Why Intlayer?' 문서](https://intlayer.org/doc/why)를 참조하세요.
|