@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,284 +1,162 @@
|
|
|
1
1
|
---
|
|
2
|
-
createdAt:
|
|
3
|
-
updatedAt: 2025-
|
|
2
|
+
createdAt: 2025-08-23
|
|
3
|
+
updatedAt: 2025-08-23
|
|
4
4
|
title: next-i18next vs next-intl vs Intlayer
|
|
5
|
-
description: Next.js
|
|
5
|
+
description: Next.js 앱의 국제화(i18n)를 위해 next-i18next와 next-intl, Intlayer를 비교합니다
|
|
6
6
|
keywords:
|
|
7
7
|
- next-intl
|
|
8
8
|
- next-i18next
|
|
9
9
|
- Intlayer
|
|
10
10
|
- 국제화
|
|
11
|
-
-
|
|
11
|
+
- 블로그
|
|
12
12
|
- Next.js
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- 자바스크립트
|
|
14
|
+
- 리액트
|
|
15
15
|
slugs:
|
|
16
16
|
- blog
|
|
17
17
|
- next-i18next-vs-next-intl-vs-intlayer
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
# next-i18next VS next-intl VS
|
|
20
|
+
# next-i18next VS next-intl VS intlayer | Next.js 국제화(i18n)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
이 가이드는 **Next.js**에서 널리 사용되는 세 가지 i18n 옵션인 **next-intl**, **next-i18next**, 그리고 **Intlayer**를 비교합니다.
|
|
23
|
+
우리는 **Next.js 13+ App Router** (및 **React Server Components**)에 중점을 두고 다음 항목들을 평가합니다:
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
1. **아키텍처 및 콘텐츠 구성**
|
|
26
|
+
2. **TypeScript 및 안정성**
|
|
27
|
+
3. **누락된 번역 처리**
|
|
28
|
+
4. **라우팅 및 미들웨어**
|
|
29
|
+
5. **성능 및 로딩 동작**
|
|
30
|
+
6. **개발자 경험(DX), 도구 및 유지보수**
|
|
31
|
+
7. **SEO 및 대규모 프로젝트 확장성**
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
2. **TypeScript 지원**
|
|
28
|
-
3. **누락된 번역 관리**
|
|
29
|
-
4. **서버 구성 요소 지원**
|
|
30
|
-
5. **Next.js에 대한 향상된 라우팅 및 미들웨어**
|
|
31
|
-
6. **설정의 간단함**
|
|
32
|
-
|
|
33
|
-
이 가이드는 또한 **Intlayer**에 대한 **심층 분석**을 제공하며, 특히 **App Router** 및 **Server Components**를 포함한 Next.js 13+에 대한 강력한 선택인 이유를 보여줍니다.
|
|
33
|
+
> **요약**: 세 가지 모두 Next.js 앱을 현지화할 수 있습니다. 만약 **컴포넌트 범위 콘텐츠**, **엄격한 TypeScript 타입**, **빌드 타임 누락 키 검사**, **트리 쉐이킹된 사전**, 그리고 **최고급 App Router + SEO 도우미**를 원한다면, **Intlayer**가 가장 완전하고 현대적인 선택입니다.
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
### 1. next-intl
|
|
37
|
+
## 상위 수준 포지셔닝
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
- **next-intl** - 가볍고 직관적인 메시지 포맷팅을 제공하며 Next.js 지원이 탄탄합니다. 중앙 집중식 카탈로그가 일반적이며, 개발자 경험은 단순하지만 안정성과 대규모 유지보수는 주로 사용자의 책임입니다.
|
|
40
|
+
- **next-i18next** - Next.js 환경에 맞춘 i18next입니다. 성숙한 생태계와 플러그인(예: ICU)을 통한 기능을 제공하지만, 설정이 장황할 수 있고 프로젝트가 커질수록 카탈로그가 중앙 집중화되는 경향이 있습니다.
|
|
41
|
+
- **Intlayer** - Next.js를 위한 컴포넌트 중심 콘텐츠 모델로, **엄격한 TS 타입 지정**, **빌드 타임 검사**, **트리 쉐이킹**, **내장 미들웨어 및 SEO 도우미**, 선택적 **비주얼 에디터/CMS**, 그리고 **AI 지원 번역**을 제공합니다.
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
- **TypeScript 지원**: 기본 TypeScript 통합. 일부 타입 정의가 존재하지만, 번역 파일에서 TypeScript 정의를 자동 생성하는 데 중점을 두지 않습니다.
|
|
45
|
-
- **누락된 번역**: 기본적인 폴백 메커니즘. 기본적으로 키 또는 기본 로케일 문자열로 폴백됩니다. 고급 누락된 번역 검사를 위한 강력한 도구는 제공되지 않습니다.
|
|
46
|
-
- **서버 구성 요소 지원**: 일반적으로 Next.js 13+와 함께 작동하지만, 패턴이 깊은 서버측 사용(예: 복잡한 동적 라우팅을 가진 서버 구성 요소)에 덜 전문화되어 있습니다.
|
|
47
|
-
- **라우팅 및 미들웨어**: 미들웨어 지원이 가능하지만 제한적입니다. 일반적으로 로케일 감지를 위해 Next.js `Middleware`에 의존하거나, 로케일 경로 재작성을 위해 수동 구성이 필요합니다.
|
|
48
|
-
- **설정의 간단함**: 매우 직관적입니다. 최소한의 보일러플레이트가 필요합니다.
|
|
43
|
+
---
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
## 나란히 비교한 기능 비교 (Next.js 중심)
|
|
46
|
+
|
|
47
|
+
| 기능 | `next-intlayer` (Intlayer) | `next-intl` | `next-i18next` |
|
|
48
|
+
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
49
|
+
| **컴포넌트 근처 번역** | ✅ 예, 각 컴포넌트와 함께 콘텐츠가 배치됨 | ❌ 아니요 | ❌ 아니요 |
|
|
50
|
+
| **TypeScript 통합** | ✅ 고급, 자동 생성된 엄격한 타입 | ✅ 우수 | ⚠️ 기본 |
|
|
51
|
+
| **누락된 번역 감지** | ✅ TypeScript 오류 하이라이트 및 빌드 시 오류/경고 | ⚠️ 런타임 폴백 | ⚠️ 런타임 폴백 |
|
|
52
|
+
| **리치 콘텐츠 (JSX/Markdown/컴포넌트)** | ✅ 직접 지원 | ❌ 리치 노드용으로 설계되지 않음 | ⚠️ 제한적 지원 |
|
|
53
|
+
| **AI 기반 번역** | ✅ 예, 여러 AI 제공자를 지원합니다. 자체 API 키를 사용하여 사용할 수 있습니다. 애플리케이션 및 콘텐츠 범위의 컨텍스트를 고려합니다. | ❌ 아니요 | ❌ 아니요 |
|
|
54
|
+
| **비주얼 에디터** | ✅ 예, 로컬 비주얼 에디터 + 선택적 CMS; 코드베이스 콘텐츠를 외부화할 수 있으며, 임베드 가능 | ❌ 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | ❌ 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 |
|
|
55
|
+
| **로컬라이즈된 라우팅** | ✅ 예, 기본적으로 로컬라이즈된 경로를 지원합니다 (Next.js 및 Vite와 함께 작동) | ✅ 내장, App Router가 `[locale]` 세그먼트를 지원합니다 | ✅ 내장 |
|
|
56
|
+
| **동적 라우트 생성** | ✅ 예 | ✅ 예 | ✅ 예 |
|
|
57
|
+
| **복수형 처리** | ✅ 열거형 기반 패턴 | ✅ 우수함 | ✅ 우수함 |
|
|
58
|
+
| **형식 지정 (날짜, 숫자, 통화)** | ✅ 최적화된 포매터 (내부적으로 Intl 사용) | ✅ 우수함 (Intl 헬퍼) | ✅ 우수함 (Intl 헬퍼) |
|
|
59
|
+
| **콘텐츠 형식** | ✅ .tsx, .ts, .js, .json, .md, .txt, (.yaml 작업 중) | ✅ .json, .js, .ts | ⚠️ .json |
|
|
60
|
+
| **ICU 지원** | ⚠️ 작업 중 | ✅ 예 | ⚠️ 플러그인 통해 (`i18next-icu`) |
|
|
61
|
+
| **SEO 도우미 (hreflang, 사이트맵)** | ✅ 내장 도구: 사이트맵, robots.txt, 메타데이터 도우미 | ✅ 우수 | ✅ 우수 |
|
|
62
|
+
| **생태계 / 커뮤니티** | ⚠️ 규모는 작지만 빠르게 성장하고 반응성이 좋음 | ✅ 중간 규모, Next.js 중심 | ✅ 중간 규모, Next.js 중심 |
|
|
63
|
+
| **서버 사이드 렌더링 및 서버 컴포넌트** | ✅ 예, SSR 및 React 서버 컴포넌트에 최적화됨 | ⚠️ 페이지 단위로 지원되나 자식 서버 컴포넌트에 t-함수를 컴포넌트 트리를 통해 전달해야 함 | ⚠️ 페이지 단위로 지원되나 자식 서버 컴포넌트에 t-함수를 컴포넌트 트리를 통해 전달해야 함 |
|
|
64
|
+
| **트리 쉐이킹 (사용된 콘텐츠만 로드)** | ✅ 예, Babel/SWC 플러그인을 통한 빌드 시 컴포넌트별 적용 | ⚠️ 부분적 지원 | ⚠️ 부분적 지원 |
|
|
65
|
+
| **지연 로딩 (Lazy loading)** | ✅ 예, 로케일별 / 사전별 | ✅ 예 (경로별/로케일별), 네임스페이스 관리 필요 | ✅ 예 (경로별/로케일별), 네임스페이스 관리 필요 |
|
|
66
|
+
| **사용하지 않는 콘텐츠 정리 (Purge unused content)** | ✅ 예, 빌드 시 사전별 | ❌ 아니요, 네임스페이스 관리를 통해 수동으로 관리 가능 | ❌ 아니요, 네임스페이스 관리를 통해 수동으로 관리 가능 |
|
|
67
|
+
| **대규모 프로젝트 관리** | ✅ 모듈화 권장, 디자인 시스템에 적합 | ✅ 설정과 함께 모듈화 | ✅ 설정과 함께 모듈화 |
|
|
51
68
|
|
|
52
69
|
---
|
|
53
70
|
|
|
54
|
-
|
|
71
|
+
## 심층 비교
|
|
55
72
|
|
|
56
|
-
|
|
73
|
+
### 1) 아키텍처 및 확장성
|
|
57
74
|
|
|
58
|
-
-
|
|
59
|
-
- **
|
|
60
|
-
- **누락된 번역**: i18next는 보간/폴백을 제공합니다. 그러나 누락된 번역 감지는 일반적으로 추가 설정이나 서드파티 플러그인이 필요합니다.
|
|
61
|
-
- **서버 구성 요소 지원**: Next.js 13과 함께 사용하는 기본적인 방법은 문서화되어 있지만, 고급 사용(예: 서버 구성 요소와의 깊은 통합, 동적 경로 생성)은 번거로울 수 있습니다.
|
|
62
|
-
- **라우팅 및 미들웨어**: Next.js `Middleware`와 로케일 하위 경로 재작성에 크게 의존합니다. 더 복잡한 설정의 경우, 고급 i18next 구성을 들어가야 할 수 있습니다.
|
|
63
|
-
- **설정의 간단함**: i18next에 익숙한 사람들에게는 친숙한 접근 방식입니다. 그러나 고급 i18n 기능이 필요할 때 보일러플레이트가 더 많이 발생할 수 있습니다(네임스페이스, 여러 대체 로케일 등).
|
|
75
|
+
- **next-intl / next-i18next**: 기본적으로 로케일별 **중앙 집중식 카탈로그** (그리고 i18next의 **네임스페이스**)를 사용합니다. 초기에는 잘 작동하지만, 시간이 지남에 따라 결합도가 높아지고 키 변경이 빈번해지면서 큰 공유 영역이 되는 경우가 많습니다.
|
|
76
|
+
- **Intlayer**: 코드와 함께 **컴포넌트별**(또는 기능별) 사전을 **같은 위치에 배치**하도록 권장합니다. 이는 인지 부하를 줄이고, UI 조각의 복제/이동을 용이하게 하며, 팀 간 충돌을 줄여줍니다. 사용하지 않는 콘텐츠는 자연스럽게 쉽게 발견되고 제거할 수 있습니다.
|
|
64
77
|
|
|
65
|
-
|
|
78
|
+
**중요한 이유:** 대규모 코드베이스나 디자인 시스템 환경에서는 **모듈화된 콘텐츠**가 단일 카탈로그보다 더 잘 확장됩니다.
|
|
66
79
|
|
|
67
80
|
---
|
|
68
81
|
|
|
69
|
-
###
|
|
70
|
-
|
|
71
|
-
**주요 초점**: Next.js **App Router**(12, 13, 14, 15) 전용으로 특별히 설계된 현대적인 오픈 소스 i18n 라이브러리로, **Server Components** 및 **Turbopack**에 대한 기본 지원이 있습니다.
|
|
82
|
+
### 2) TypeScript 및 안정성
|
|
72
83
|
|
|
73
|
-
|
|
84
|
+
- **next-intl**: 견고한 TypeScript 지원을 제공하지만, **키가 기본적으로 엄격하게 타입 지정되지 않으므로** 안전성 패턴을 수동으로 유지해야 합니다.
|
|
85
|
+
- **next-i18next**: 훅에 대한 기본 타입 정의를 제공하지만, **엄격한 키 타입 지정은 추가 도구/구성이 필요합니다**.
|
|
86
|
+
- **Intlayer**: 콘텐츠에서 **엄격한 타입을 생성**합니다. **IDE 자동완성**과 **컴파일 타임 오류**가 배포 전에 오타와 누락된 키를 잡아냅니다.
|
|
74
87
|
|
|
75
|
-
|
|
88
|
+
**중요한 이유:** 강력한 타입 지정은 실패를 **오른쪽(런타임)**이 아닌 **왼쪽(CI/빌드)**으로 이동시킵니다.
|
|
76
89
|
|
|
77
|
-
|
|
78
|
-
- 이는 특히 대규모 코드베이스에서 코드의 **모듈화 및 유지보수성**을 높여줍니다.
|
|
79
|
-
|
|
80
|
-
2. **TypeScript 지원**
|
|
81
|
-
|
|
82
|
-
- **자동 생성된 타입 정의**: 콘텐츠를 정의하는 순간 Intlayer는 자동 완성 및 번역 오류 포착을 제공하는 타입을 생성합니다.
|
|
83
|
-
- 누락된 키와 같은 런타임 오류를 최소화하고 IDE에서 직접 고급 **자동 완성**을 제공합니다.
|
|
84
|
-
|
|
85
|
-
3. **누락된 번역 관리**
|
|
90
|
+
---
|
|
86
91
|
|
|
87
|
-
|
|
88
|
-
- 이를 통해 모든 언어로 누락된 텍스트가 실수로 배포되는 일을 방지합니다.
|
|
92
|
+
### 3) 누락된 번역 처리
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
- **next-intl / next-i18next**: **런타임 폴백**에 의존합니다(예: 키 또는 기본 로케일 표시). 빌드는 실패하지 않습니다.
|
|
95
|
+
- **Intlayer**: 누락된 로케일이나 키에 대해 **빌드 타임 감지**와 **경고/오류**를 제공합니다.
|
|
91
96
|
|
|
92
|
-
|
|
93
|
-
- **서버 컨텍스트를 격리**하기 위한 특수 제공자(`IntlayerServerProvider`, `IntlayerClientProvider`)를 제공합니다 (Next.js 13+에서 중요합니다).
|
|
97
|
+
**중요한 이유:** 빌드 중에 누락을 잡으면 프로덕션에서 “미스터리 문자열”이 발생하는 것을 방지하고 엄격한 릴리스 게이트와 일치합니다.
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
---
|
|
96
100
|
|
|
97
|
-
|
|
98
|
-
- 대체 언어 링크를 생성하기 위한 `getMultilingualUrls`와 같은 도우미 메서드를 제공합니다 (SEO에 유용합니다).
|
|
101
|
+
### 4) 라우팅, 미들웨어 및 URL 전략
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- 콘텐츠에 대한 모든 환경 변수와 감시를 **주입하는** 래퍼 플러그인 `withIntlayer(nextConfig)`이 필요합니다.
|
|
103
|
-
- **큰 폴백 구성 필요 없음**, 시스템이 최소한의 마찰로 “그냥 작동”하도록 설계되었습니다.
|
|
103
|
+
- 세 가지 모두 App Router에서 **Next.js 지역화 라우팅**을 지원합니다.
|
|
104
|
+
- **Intlayer**는 **i18n 미들웨어**(헤더/쿠키를 통한 로케일 감지)와 **로컬라이즈된 URL 및 `<link rel="alternate" hreflang="…">` 태그 생성을 위한 헬퍼**를 제공하여 한 단계 더 나아갑니다.
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
**중요한 이유:** 커스텀 연결 계층이 줄어들고, **일관된 사용자 경험(UX)**과 **깔끔한 SEO**가 로케일 전반에 걸쳐 유지됩니다.
|
|
106
107
|
|
|
107
108
|
---
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
| **기능** | **next-intl** | **next-i18next** | **Intlayer** |
|
|
112
|
-
| -------------------------------- | --------------------------------------- | --------------------------------------- | ---------------------------------- |
|
|
113
|
-
| **번역을 구성 요소 근처에 유지** | 부분적 - 일반적으로 한 개의 로케일 폴더 | 기본값 아님 - 종종 `public/locales` | **예 - 권장 및 간단** |
|
|
114
|
-
| **TypeScript 자동 생성** | 기본 TS 정의 | 기본 TS 지원 | **예 - 고급 기능 제공** |
|
|
115
|
-
| **누락된 번역 감지** | 대부분 폴백 문자열 | 대부분 폴백 문자열 | **예 - 빌드 시 검사** |
|
|
116
|
-
| **서버 구성 요소 지원** | 작동하지만 전문화되지 않음 | 지원되지만 다소 번거로울 수 있음 | **전문 제공자를 통한 완전 지원** |
|
|
117
|
-
| **라우팅 및 미들웨어** | Next 미들웨어와 수동 통합 | 재작성 구성을 통해 제공 | **전용 i18n 미들웨어 + 고급 후크** |
|
|
118
|
-
| **설정 복잡성** | 간단, 최소한의 구성 | 전통적, 고급 사용 위해 번거로울 수 있음 | **하나의 구성 파일 및 플러그인** |
|
|
119
|
-
|
|
120
|
-
---
|
|
110
|
+
### 5) 서버 컴포넌트(RSC) 정렬
|
|
121
111
|
|
|
122
|
-
|
|
112
|
+
- **모두** Next.js 13+를 지원합니다.
|
|
113
|
+
- **Intlayer**는 RSC를 위해 설계된 일관된 API와 프로바이더를 통해 **서버/클라이언트 경계**를 매끄럽게 처리하여, 포매터나 t-함수를 컴포넌트 트리를 통해 전달할 필요가 없습니다.
|
|
123
114
|
|
|
124
|
-
|
|
115
|
+
**중요한 이유:** 더 깔끔한 정신 모델과 하이브리드 트리에서 발생하는 예외 상황이 줄어듭니다.
|
|
125
116
|
|
|
126
|
-
|
|
117
|
+
---
|
|
127
118
|
|
|
128
|
-
|
|
119
|
+
### 6) 성능 및 로딩 동작
|
|
129
120
|
|
|
130
|
-
|
|
121
|
+
- **next-intl / next-i18next**: **네임스페이스**와 **라우트 수준 분할**을 통해 부분적인 제어가 가능하지만, 규율이 느슨해지면 사용하지 않는 문자열이 번들에 포함될 위험이 있습니다.
|
|
122
|
+
- **Intlayer**: 빌드 시 **트리 쉐이킹**을 수행하고, 사전/로케일별로 **지연 로딩**합니다. 사용하지 않는 콘텐츠는 포함되지 않습니다.
|
|
131
123
|
|
|
132
|
-
|
|
124
|
+
**중요한 이유:** 특히 다국어 사이트에서 더 작은 번들 크기와 더 빠른 시작 속도를 제공합니다.
|
|
133
125
|
|
|
134
|
-
|
|
126
|
+
---
|
|
135
127
|
|
|
136
|
-
|
|
128
|
+
### 7) 개발자 경험(DX), 도구 및 유지보수
|
|
137
129
|
|
|
138
|
-
|
|
130
|
+
- **next-intl / next-i18next**: 일반적으로 번역 및 편집 워크플로우를 위해 외부 플랫폼과 연동해야 합니다.
|
|
131
|
+
- **Intlayer**: **무료 비주얼 에디터**와 **선택적 CMS**(Git 친화적이거나 외부화 가능)를 제공합니다. 또한 콘텐츠 작성용 **VSCode 확장**과 자체 제공자 키를 사용하는 **AI 지원 번역** 기능도 포함되어 있습니다.
|
|
139
132
|
|
|
140
|
-
|
|
141
|
-
- 표준 `intlayerMiddleware`는 깊은 사용자 지정 재작성이 필요하지 않습니다.
|
|
133
|
+
**중요한 이유:** 운영 비용을 낮추고 개발자와 콘텐츠 작성자 간의 피드백 루프를 단축합니다.
|
|
142
134
|
|
|
143
|
-
|
|
135
|
+
---
|
|
144
136
|
|
|
145
|
-
|
|
146
|
-
- `IntlayerServerProvider`와 `IntlayerClientProvider`를 통해 **서버** 및 **클라이언트** 구성 요소에 대해 명확하고 직관적인 사용법을 제공합니다.
|
|
137
|
+
## 언제 어떤 것을 선택해야 할까요?
|
|
147
138
|
|
|
148
|
-
|
|
149
|
-
|
|
139
|
+
- **next-intl**를 선택하세요, 만약 **최소한의** 솔루션을 원하고, 중앙 집중식 카탈로그에 익숙하며, 앱이 **작거나 중간 규모**인 경우.
|
|
140
|
+
- **next-i18next**를 선택하세요, 만약 **i18next의 플러그인 생태계**(예: 플러그인을 통한 고급 ICU 규칙)가 필요하고, 팀이 이미 i18next를 알고 있으며, 유연성을 위해 **더 많은 설정**을 감수할 수 있는 경우.
|
|
141
|
+
- **Intlayer**를 선택하세요, 만약 **컴포넌트 범위의 콘텐츠**, **엄격한 TypeScript**, **빌드 타임 보장**, **트리 쉐이킹**, 그리고 **내장된 라우팅/SEO/에디터 도구**를 중요하게 생각한다면 - 특히 **Next.js App Router**와 **대규모 모듈식 코드베이스**에 적합합니다.
|
|
150
142
|
|
|
151
143
|
---
|
|
152
144
|
|
|
153
|
-
##
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
1. **설치 및 구성**
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
npm install intlayer next-intlayer
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
|
-
// intlayer.config.ts
|
|
168
|
-
import { Locales, type IntlayerConfig } from "intlayer";
|
|
169
|
-
|
|
170
|
-
const config: IntlayerConfig = {
|
|
171
|
-
internationalization: {
|
|
172
|
-
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
173
|
-
defaultLocale: Locales.ENGLISH,
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
export default config;
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. **플러그인 사용**
|
|
180
|
-
|
|
181
|
-
```ts
|
|
182
|
-
// next.config.mjs
|
|
183
|
-
import { withIntlayer } from "next-intlayer/server";
|
|
184
|
-
|
|
185
|
-
/** @type {import('next').NextConfig} */
|
|
186
|
-
const nextConfig = {};
|
|
187
|
-
|
|
188
|
-
export default withIntlayer(nextConfig);
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
3. **미들웨어 추가**
|
|
192
|
-
|
|
193
|
-
```ts
|
|
194
|
-
// src/middleware.ts
|
|
195
|
-
export { intlayerMiddleware as middleware } from "next-intlayer/middleware";
|
|
196
|
-
|
|
197
|
-
export const config = {
|
|
198
|
-
matcher:
|
|
199
|
-
"/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
|
|
200
|
-
};
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
4. **지역화된 레이아웃 생성**
|
|
204
|
-
|
|
205
|
-
```tsx
|
|
206
|
-
// src/app/[locale]/layout.tsx
|
|
207
|
-
import { getHTMLTextDir } from "intlayer";
|
|
208
|
-
import { NextLayoutIntlayer } from "next-intlayer";
|
|
209
|
-
|
|
210
|
-
const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
|
|
211
|
-
const { locale } = params;
|
|
212
|
-
return (
|
|
213
|
-
<html lang={locale} dir={getHTMLTextDir(locale)}>
|
|
214
|
-
<body>{children}</body>
|
|
215
|
-
</html>
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
export { generateStaticParams } from "next-intlayer";
|
|
220
|
-
export default LocaleLayout;
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
5. **콘텐츠 선언 및 사용**
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
// src/app/[locale]/page.content.ts
|
|
227
|
-
import { t } from "intlayer";
|
|
228
|
-
|
|
229
|
-
export default {
|
|
230
|
-
key: "page",
|
|
231
|
-
content: {
|
|
232
|
-
getStarted: {
|
|
233
|
-
main: t({
|
|
234
|
-
en: "Get started by editing",
|
|
235
|
-
fr: "Commencez par éditer",
|
|
236
|
-
es: "Comience por editar",
|
|
237
|
-
}),
|
|
238
|
-
pageLink: "src/app/page.tsx",
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
};
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
```tsx
|
|
245
|
-
// src/app/[locale]/page.tsx
|
|
246
|
-
import { IntlayerServerProvider } from "next-intlayer/server";
|
|
247
|
-
import { IntlayerClientProvider, useIntlayer } from "next-intlayer";
|
|
248
|
-
|
|
249
|
-
const PageContent = () => {
|
|
250
|
-
const { content } = useIntlayer("page");
|
|
251
|
-
return (
|
|
252
|
-
<>
|
|
253
|
-
<p>{content.getStarted.main}</p>
|
|
254
|
-
<code>{content.getStarted.pageLink}</code>
|
|
255
|
-
</>
|
|
256
|
-
);
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
export default function Page({ params }) {
|
|
260
|
-
return (
|
|
261
|
-
<IntlayerServerProvider locale={params.locale}>
|
|
262
|
-
<IntlayerClientProvider locale={params.locale}>
|
|
263
|
-
<PageContent />
|
|
264
|
-
</IntlayerClientProvider>
|
|
265
|
-
</IntlayerServerProvider>
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
</details>
|
|
145
|
+
## 실용적인 마이그레이션 노트 (next-intl / next-i18next → Intlayer)
|
|
146
|
+
|
|
147
|
+
- **기능별로 시작하기**: 한 번에 하나의 라우트나 컴포넌트를 **로컬 사전**으로 옮기세요.
|
|
148
|
+
- **기존 카탈로그 병행 유지**: 마이그레이션 중에 다리를 놓듯 사용하세요; 한꺼번에 전환하는 것은 피하세요.
|
|
149
|
+
- **엄격한 검사 활성화**: 빌드 타임에 누락된 부분을 조기에 발견할 수 있게 하세요.
|
|
150
|
+
- **미들웨어 및 헬퍼 도입**: 사이트 전반에 걸쳐 로케일 감지와 SEO 태그를 표준화하세요.
|
|
151
|
+
- **번들 크기 측정**: 사용하지 않는 콘텐츠가 제거되면서 **번들 크기 감소**를 기대하세요.
|
|
271
152
|
|
|
272
153
|
---
|
|
273
154
|
|
|
274
155
|
## 결론
|
|
275
156
|
|
|
276
|
-
|
|
157
|
+
세 라이브러리 모두 핵심 로컬라이제이션에서는 성공적입니다. 차이점은 **현대적인 Next.js 환경에서 견고하고 확장 가능한 설정을 위해 얼마나 많은 작업을 해야 하는가**에 있습니다:
|
|
277
158
|
|
|
278
|
-
-
|
|
279
|
-
-
|
|
280
|
-
- **안전한 코드 작성을 위한 강력한 TypeScript 자동 생성 제공**
|
|
281
|
-
- **누락된 번역을 빌드 시에 처리**
|
|
282
|
-
- **고급 라우팅 및 미들웨어와 함께 단일 구성 접근 방식을 제공**
|
|
159
|
+
- **Intlayer**를 사용하면, **모듈화된 콘텐츠**, **엄격한 TS(타입스크립트)**, **빌드 타임 안전성**, **트리 쉐이킹된 번들**, 그리고 **최고급 App Router 및 SEO 도구**가 **기본값**으로 제공되며, 번거로운 작업이 아닙니다.
|
|
160
|
+
- 다국어, 컴포넌트 기반 앱에서 **유지보수성과 속도**를 중요시하는 팀이라면, Intlayer가 오늘날 가장 **완벽한** 경험을 제공합니다.
|
|
283
161
|
|
|
284
|
-
|
|
162
|
+
자세한 내용은 ['Why Intlayer?' 문서](https://intlayer.org/doc/why)를 참조하세요.
|