@intlayer/docs 9.3.0 → 9.3.2
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/README.md +24 -24
- package/blog/ar/rag_powered_documentation_assistant.md +1 -1
- package/blog/pl/rag_powered_documentation_assistant.md +1 -1
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/authors2.cjs +0 -1
- package/dist/cjs/common.cjs.map +1 -1
- package/dist/cjs/generated/blog.entry.cjs +4 -2
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +24 -2
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +4 -2
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +4 -2
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +4 -2
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +24 -2
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +4 -2
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +4 -2
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/configuration.md +10 -10
- package/docs/ar/eslint.md +336 -0
- package/docs/ar/interest_of_intlayer.md +24 -22
- package/docs/ar/intlayer_with_express.md +1 -1
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/ar/intlayer_with_svelte_kit.md +1 -1
- package/docs/ar/intlayer_with_tanstack+solid.md +5 -3
- package/docs/ar/intlayer_with_tanstack.md +5 -3
- package/docs/ar/lsp.md +114 -175
- package/docs/ar/readme.md +25 -25
- package/docs/bn/configuration.md +10 -10
- package/docs/bn/eslint.md +336 -0
- package/docs/bn/interest_of_intlayer.md +24 -22
- package/docs/cs/configuration.md +10 -10
- package/docs/cs/eslint.md +336 -0
- package/docs/cs/interest_of_intlayer.md +24 -22
- package/docs/de/configuration.md +10 -10
- package/docs/de/eslint.md +336 -0
- package/docs/de/interest_of_intlayer.md +24 -22
- package/docs/de/intlayer_with_svelte_kit.md +1 -1
- package/docs/de/intlayer_with_tanstack+solid.md +5 -3
- package/docs/de/intlayer_with_tanstack.md +5 -3
- package/docs/de/lsp.md +111 -172
- package/docs/de/readme.md +24 -24
- package/docs/en/configuration.md +10 -10
- package/docs/en/eslint.md +336 -0
- package/docs/en/interest_of_intlayer.md +24 -22
- package/docs/en/intlayer_with_svelte_kit.md +1 -1
- package/docs/en/intlayer_with_tanstack+solid.md +5 -3
- package/docs/en/intlayer_with_tanstack.md +5 -3
- package/docs/en/lsp.md +109 -170
- package/docs/en/readme.md +24 -24
- package/docs/en-GB/configuration.md +10 -10
- package/docs/en-GB/eslint.md +336 -0
- package/docs/en-GB/interest_of_intlayer.md +24 -22
- package/docs/en-GB/intlayer_with_create_react_app.md +32 -35
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/en-GB/intlayer_with_svelte_kit.md +1 -1
- package/docs/en-GB/intlayer_with_tanstack+solid.md +5 -3
- package/docs/en-GB/intlayer_with_tanstack.md +5 -3
- package/docs/en-GB/lsp.md +109 -170
- package/docs/en-GB/readme.md +24 -24
- package/docs/es/configuration.md +10 -10
- package/docs/es/eslint.md +336 -0
- package/docs/es/interest_of_intlayer.md +24 -22
- package/docs/es/intlayer_with_svelte_kit.md +1 -1
- package/docs/es/intlayer_with_tanstack+solid.md +5 -3
- package/docs/es/intlayer_with_tanstack.md +5 -3
- package/docs/es/lsp.md +114 -175
- package/docs/es/readme.md +24 -24
- package/docs/fr/configuration.md +10 -10
- package/docs/fr/eslint.md +336 -0
- package/docs/fr/interest_of_intlayer.md +24 -22
- package/docs/fr/intlayer_with_svelte_kit.md +1 -1
- package/docs/fr/intlayer_with_tanstack+solid.md +5 -3
- package/docs/fr/intlayer_with_tanstack.md +5 -3
- package/docs/fr/lsp.md +110 -171
- package/docs/fr/readme.md +24 -24
- package/docs/hi/configuration.md +10 -10
- package/docs/hi/eslint.md +336 -0
- package/docs/hi/interest_of_intlayer.md +24 -22
- package/docs/hi/intlayer_with_express.md +1 -1
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/hi/intlayer_with_svelte_kit.md +1 -1
- package/docs/hi/intlayer_with_tanstack+solid.md +5 -3
- package/docs/hi/intlayer_with_tanstack.md +5 -3
- package/docs/hi/intlayer_with_vite+svelte.md +2 -2
- package/docs/hi/lsp.md +113 -174
- package/docs/hi/readme.md +24 -24
- package/docs/id/configuration.md +10 -10
- package/docs/id/eslint.md +336 -0
- package/docs/id/interest_of_intlayer.md +24 -22
- package/docs/id/intlayer_with_svelte_kit.md +1 -1
- package/docs/id/intlayer_with_tanstack+solid.md +5 -3
- package/docs/id/intlayer_with_tanstack.md +5 -3
- package/docs/id/lsp.md +113 -174
- package/docs/id/readme.md +24 -24
- package/docs/it/configuration.md +10 -10
- package/docs/it/eslint.md +336 -0
- package/docs/it/interest_of_intlayer.md +24 -22
- package/docs/it/intlayer_with_svelte_kit.md +1 -1
- package/docs/it/intlayer_with_tanstack+solid.md +5 -3
- package/docs/it/intlayer_with_tanstack.md +5 -3
- package/docs/it/lsp.md +115 -176
- package/docs/it/readme.md +24 -24
- package/docs/ja/configuration.md +10 -10
- package/docs/ja/eslint.md +336 -0
- package/docs/ja/interest_of_intlayer.md +24 -22
- package/docs/ja/intlayer_with_react_router_v7.md +1 -146
- package/docs/ja/intlayer_with_tanstack+solid.md +5 -3
- package/docs/ja/intlayer_with_tanstack.md +5 -3
- package/docs/ja/intlayer_with_vite+react.md +5 -1
- package/docs/ja/lsp.md +113 -174
- package/docs/ja/readme.md +24 -24
- package/docs/ko/configuration.md +10 -10
- package/docs/ko/eslint.md +336 -0
- package/docs/ko/interest_of_intlayer.md +24 -22
- package/docs/ko/intlayer_with_lynx+react.md +4 -0
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/ko/intlayer_with_storybook.md +5 -5
- package/docs/ko/intlayer_with_svelte_kit.md +1 -1
- package/docs/ko/intlayer_with_tanstack+solid.md +5 -3
- package/docs/ko/intlayer_with_tanstack.md +5 -3
- package/docs/ko/lsp.md +112 -173
- package/docs/ko/readme.md +24 -24
- package/docs/nl/configuration.md +10 -10
- package/docs/nl/eslint.md +336 -0
- package/docs/nl/interest_of_intlayer.md +24 -22
- package/docs/pl/configuration.md +10 -10
- package/docs/pl/eslint.md +336 -0
- package/docs/pl/interest_of_intlayer.md +4 -2
- package/docs/pl/intlayer_with_astro.md +1 -114
- package/docs/pl/intlayer_with_svelte_kit.md +1 -1
- package/docs/pl/intlayer_with_tanstack+solid.md +5 -3
- package/docs/pl/intlayer_with_tanstack.md +5 -3
- package/docs/pl/lsp.md +115 -176
- package/docs/pl/migration_from_i18next_to_intlayer.md +4 -0
- package/docs/pl/migration_from_next-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_next-intl_to_intlayer.md +11 -5
- package/docs/pl/migration_from_nuxtjs_i18n_to_intlayer.md +8 -4
- package/docs/pl/migration_from_react-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_vue-i18n_to_intlayer.md +4 -0
- package/docs/pl/readme.md +24 -24
- package/docs/pt/configuration.md +10 -10
- package/docs/pt/eslint.md +336 -0
- package/docs/pt/interest_of_intlayer.md +24 -22
- package/docs/pt/intlayer_with_astro.md +1 -114
- package/docs/pt/intlayer_with_svelte_kit.md +1 -1
- package/docs/pt/intlayer_with_tanstack+solid.md +5 -3
- package/docs/pt/intlayer_with_tanstack.md +5 -3
- package/docs/pt/lsp.md +113 -174
- package/docs/pt/readme.md +24 -24
- package/docs/ru/configuration.md +10 -10
- package/docs/ru/eslint.md +336 -0
- package/docs/ru/interest_of_intlayer.md +24 -22
- package/docs/ru/intlayer_with_nextjs_14.md +1 -1
- package/docs/ru/intlayer_with_nextjs_15.md +1 -1
- package/docs/ru/intlayer_with_svelte_kit.md +1 -1
- package/docs/ru/intlayer_with_tanstack+solid.md +5 -3
- package/docs/ru/intlayer_with_tanstack.md +5 -3
- package/docs/ru/lsp.md +112 -173
- package/docs/ru/readme.md +24 -24
- package/docs/tr/configuration.md +10 -10
- package/docs/tr/eslint.md +336 -0
- package/docs/tr/interest_of_intlayer.md +24 -22
- package/docs/tr/intlayer_with_svelte_kit.md +1 -1
- package/docs/tr/intlayer_with_tanstack+solid.md +5 -3
- package/docs/tr/intlayer_with_tanstack.md +5 -3
- package/docs/tr/lsp.md +113 -174
- package/docs/tr/readme.md +24 -24
- package/docs/uk/configuration.md +10 -10
- package/docs/uk/eslint.md +336 -0
- package/docs/uk/interest_of_intlayer.md +4 -2
- package/docs/uk/intlayer_with_svelte_kit.md +1 -1
- package/docs/uk/intlayer_with_tanstack+solid.md +5 -3
- package/docs/uk/intlayer_with_tanstack.md +5 -3
- package/docs/uk/lsp.md +113 -174
- package/docs/uk/packages/angular-intlayer/exports.md +2 -2
- package/docs/uk/per_locale_file.md +1 -1
- package/docs/uk/readme.md +24 -24
- package/docs/ur/configuration.md +10 -10
- package/docs/ur/eslint.md +336 -0
- package/docs/ur/interest_of_intlayer.md +24 -22
- package/docs/vi/configuration.md +10 -10
- package/docs/vi/eslint.md +336 -0
- package/docs/vi/interest_of_intlayer.md +24 -22
- package/docs/vi/intlayer_with_svelte_kit.md +1 -1
- package/docs/vi/intlayer_with_tanstack+solid.md +5 -3
- package/docs/vi/intlayer_with_tanstack.md +5 -3
- package/docs/vi/lsp.md +115 -176
- package/docs/vi/readme.md +24 -24
- package/docs/zh/configuration.md +10 -10
- package/docs/zh/eslint.md +336 -0
- package/docs/zh/interest_of_intlayer.md +24 -22
- package/docs/zh/intlayer_with_create_react_app.md +4 -0
- package/docs/zh/intlayer_with_lynx+react.md +4 -0
- package/docs/zh/intlayer_with_nextjs_14.md +0 -2
- package/docs/zh/intlayer_with_nextjs_15.md +0 -2
- package/docs/zh/intlayer_with_nextjs_page_router.md +0 -2
- package/docs/zh/intlayer_with_nuxt.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +4 -0
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +4 -0
- package/docs/zh/intlayer_with_solid_start.md +1 -1
- package/docs/zh/intlayer_with_svelte_kit.md +1 -1
- package/docs/zh/intlayer_with_tanstack+solid.md +5 -3
- package/docs/zh/intlayer_with_tanstack.md +5 -3
- package/docs/zh/intlayer_with_vite+vue.md +0 -2
- package/docs/zh/lsp.md +113 -174
- package/docs/zh/readme.md +21 -21
- package/docs/zh-TW/eslint.md +336 -0
- package/docs/zh-TW/interest_of_intlayer.md +24 -22
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +20 -0
package/docs/ko/configuration.md
CHANGED
|
@@ -404,7 +404,7 @@ const config: IntlayerConfig = {
|
|
|
404
404
|
ai: {
|
|
405
405
|
/**
|
|
406
406
|
* 사용할 AI 프로바이더.
|
|
407
|
-
* 옵션: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio'
|
|
407
|
+
* 옵션: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio', 'moonshotai'
|
|
408
408
|
* 기본값: 'openai'
|
|
409
409
|
*/
|
|
410
410
|
provider: "openai",
|
|
@@ -1032,15 +1032,15 @@ Intlayer는 최대의 유연성을 보장하기 위해 다양한 AI 프로바이
|
|
|
1032
1032
|
- **Together.ai**
|
|
1033
1033
|
- **LM Studio**
|
|
1034
1034
|
|
|
1035
|
-
| 필드 | 설명 | 타입
|
|
1036
|
-
| -------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
1037
|
-
| `provider` | Intlayer AI 기능에 사용할 프로바이더. | `'openai'` | <br/> `'anthropic'` | <br/> `'mistral'` | <br/> `'deepseek'` | <br/> `'gemini'` | <br/> `'ollama'` | <br/> `'openrouter'` | <br/> `'alibaba'` | <br/> `'fireworks'` | <br/> `'groq'` | <br/> `'huggingface'` | <br/> `'bedrock'` | <br/> `'googleaistudio'` | <br/> `'googlevertex'` | <br/> `'togetherai'` | <br/> `'lmstudio'` | `undefined` | `'anthropic'` | 여러 프로바이더는 서로 다른 API 키가 필요하며 가격 구조도 다릅니다. |
|
|
1038
|
-
| `model` | AI 기능에 사용할 AI 모델. | `string`
|
|
1039
|
-
| `temperature` | AI 응답의 무작위성을 제어합니다. | `number`
|
|
1040
|
-
| `apiKey` | 선택한 프로바이더의 API 키. | `string`
|
|
1041
|
-
| `applicationContext` | AI가 더 정확한 번역을 생성할 수 있도록 돕는 애플리케이션에 대한 추가 컨텍스트(도메인, 대상 고객, 어조, 용어 등). | `string`
|
|
1042
|
-
| `baseURL` | AI API에 대한 기본 URL. | `string`
|
|
1043
|
-
| `dataSerialization` | AI 기능에 대한 데이터 직렬화 형식. | `'json'` | <br/> `'toon'`
|
|
1035
|
+
| 필드 | 설명 | 타입 | 기본값 | 예시 | 참고 |
|
|
1036
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1037
|
+
| `provider` | Intlayer AI 기능에 사용할 프로바이더. | `'openai'` | <br/> `'anthropic'` | <br/> `'mistral'` | <br/> `'deepseek'` | <br/> `'gemini'` | <br/> `'ollama'` | <br/> `'openrouter'` | <br/> `'alibaba'` | <br/> `'fireworks'` | <br/> `'groq'` | <br/> `'huggingface'` | <br/> `'bedrock'` | <br/> `'googleaistudio'` | <br/> `'googlevertex'` | <br/> `'togetherai'` | <br/> `'lmstudio'` | <br/> `'moonshotai'` | `undefined` | `'anthropic'` | 여러 프로바이더는 서로 다른 API 키가 필요하며 가격 구조도 다릅니다. |
|
|
1038
|
+
| `model` | AI 기능에 사용할 AI 모델. | `string` | 없음 | `'gpt-4o-2024-11-20'` | 특정 모델은 프로바이더에 따라 다릅니다. |
|
|
1039
|
+
| `temperature` | AI 응답의 무작위성을 제어합니다. | `number` | 없음 | `0.1` | 온도가 높을수록 창의적이지만 신뢰성이 낮아집니다. |
|
|
1040
|
+
| `apiKey` | 선택한 프로바이더의 API 키. | `string` | 없음 | `process.env.OPENAI_API_KEY` | 비밀로 유지해야 하며 환경 변수를 사용하세요. |
|
|
1041
|
+
| `applicationContext` | AI가 더 정확한 번역을 생성할 수 있도록 돕는 애플리케이션에 대한 추가 컨텍스트(도메인, 대상 고객, 어조, 용어 등). | `string` | 없음 | `'my custom app context'` | 규칙을 추가하는 데 사용할 수 있습니다 (예: `"URL은 번역하지 마세요"` ). |
|
|
1042
|
+
| `baseURL` | AI API에 대한 기본 URL. | `string` | 없음 | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | 로컬 또는 맞춤형 AI API 엔드포인트를 가리킬 수 있습니다. |
|
|
1043
|
+
| `dataSerialization` | AI 기능에 대한 데이터 직렬화 형식. | `'json'` | <br/> `'toon'` | `undefined` | `'toon'` | • `'json'`: 기본값, 안정적임; 더 많은 토큰 소비.<br/>• `'toon'`: 더 적은 토큰 소모, 덜 안정적임.<br/>• 모델에 로직 실행을 위한 추가 파라미터(추론 노력(reasoning effort) 등)를 전달합니다. |
|
|
1044
1044
|
|
|
1045
1045
|
---
|
|
1046
1046
|
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-08-12
|
|
3
|
+
updatedAt: 2026-08-12
|
|
4
|
+
title: ESLint 플러그인 | Intlayer 린트 규칙
|
|
5
|
+
description: eslint-plugin-intlayer를 사용하여 하드코딩된 문자열, Intlayer 컴파일러가 최적화할 수 없는 동적 호출, 사용되지 않는 사전 콘텐츠를 감지하세요. React, Vue, Svelte, Angular 및 Astro 전반에서 ESLint 및 oxlint와 함께 작동합니다.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- ESLint
|
|
9
|
+
- oxlint
|
|
10
|
+
- 린팅
|
|
11
|
+
- i18n
|
|
12
|
+
- 국제화
|
|
13
|
+
- no-raw-text
|
|
14
|
+
- 하드코딩된 문자열
|
|
15
|
+
- 사용되지 않는 번역
|
|
16
|
+
- 미사용 콘텐츠
|
|
17
|
+
- React
|
|
18
|
+
- Vue
|
|
19
|
+
- Svelte
|
|
20
|
+
- Angular
|
|
21
|
+
slugs:
|
|
22
|
+
- doc
|
|
23
|
+
- eslint
|
|
24
|
+
history:
|
|
25
|
+
- version: 9.3.1
|
|
26
|
+
date: 2026-08-12
|
|
27
|
+
changes: "초기 히스토리"
|
|
28
|
+
author: aymericzip
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# ESLint x OXLint 플러그인
|
|
32
|
+
|
|
33
|
+
`eslint-plugin-intlayer`는 TypeScript가 감지하지 못하는 i18n 실수를 잡아냅니다:
|
|
34
|
+
|
|
35
|
+
1. 사전에 등록되지 않은 **하드코딩된 텍스트**.
|
|
36
|
+
2. 타입 검사를 통과하고 실행되지만 Intlayer 컴파일러가 최적화할 수 없는 **동적 호출**.
|
|
37
|
+
3. **미사용 콘텐츠(Dead content)** — 프로젝트 내에서 아무 곳에서도 읽지 않는 사전 및 필드(선택 사항).
|
|
38
|
+
|
|
39
|
+
알 수 없는 사전 키, 알 수 없는 필드 경로 및 누락된 로케일은 이미 컴파일 에러로 처리되므로 플러그인은 이를 중복 보고하지 않습니다.
|
|
40
|
+
|
|
41
|
+
## 설치
|
|
42
|
+
|
|
43
|
+
```bash packageManager="npm"
|
|
44
|
+
npm install --save-dev eslint-plugin-intlayer
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash packageManager="pnpm"
|
|
48
|
+
pnpm add --save-dev eslint-plugin-intlayer
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash packageManager="yarn"
|
|
52
|
+
yarn add --dev eslint-plugin-intlayer
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
ESLint 9 이상(Flat config)이 필요합니다.
|
|
56
|
+
|
|
57
|
+
## 사용법
|
|
58
|
+
|
|
59
|
+
이 플러그인은 ESLint와 [oxlint](https://oxc.rs) 모두에서 동일한 규칙과 옵션으로 실행됩니다.
|
|
60
|
+
|
|
61
|
+
<Tabs defaultTab="eslint">
|
|
62
|
+
<Tab label="ESLint" value="eslint">
|
|
63
|
+
|
|
64
|
+
```javascript fileName="eslint.config.mjs" codeFormat="esm"
|
|
65
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
66
|
+
|
|
67
|
+
export default [...intlayer.configs.recommended];
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
또는 규칙을 하나씩 활성화할 수 있습니다:
|
|
71
|
+
|
|
72
|
+
```javascript fileName="eslint.config.mjs" codeFormat="esm"
|
|
73
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
74
|
+
|
|
75
|
+
export default [
|
|
76
|
+
{
|
|
77
|
+
plugins: { intlayer },
|
|
78
|
+
rules: {
|
|
79
|
+
"intlayer/no-raw-text": "warn",
|
|
80
|
+
"intlayer/static-dictionary-key": "error",
|
|
81
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
82
|
+
"intlayer/enforce-adapter-import": "warn",
|
|
83
|
+
"intlayer/no-unused-content": "warn",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
</Tab>
|
|
90
|
+
<Tab label="oxlint" value="oxlint">
|
|
91
|
+
|
|
92
|
+
```json fileName=".oxlintrc.json"
|
|
93
|
+
{
|
|
94
|
+
"jsPlugins": ["eslint-plugin-intlayer"],
|
|
95
|
+
"rules": {
|
|
96
|
+
"intlayer/no-raw-text": "warn",
|
|
97
|
+
"intlayer/static-dictionary-key": "error",
|
|
98
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
99
|
+
"intlayer/enforce-adapter-import": "warn"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
두 가지 주의 사항: oxlint의 JS 플러그인 지원은 아직 알파 단계이며, 커스텀 파서를 지원하지 않으므로 `.vue`, `.svelte`, `.astro` 및 Angular 템플릿은 oxlint에서 린트되지 않습니다. JS/TS/JSX 파일에는 oxlint를 사용하고 나머지는 ESLint를 계속 사용하세요.
|
|
105
|
+
|
|
106
|
+
`no-unused-content`는 위에서 의도적으로 제외되었습니다. 이 규칙은 규칙 컨텍스트에서 작업 디렉터리와 린트 대상 파일 경로를 필요로 하지만, 알파 단계의 JS 플러그인 브리지에서는 이를 보장하지 못합니다. 이 규칙은 ESLint에서 실행하세요.
|
|
107
|
+
|
|
108
|
+
</Tab>
|
|
109
|
+
</Tabs>
|
|
110
|
+
|
|
111
|
+
### 설정 (Configs)
|
|
112
|
+
|
|
113
|
+
| 설정 | `no-raw-text` | `static-dictionary-key` | `no-dynamic-field-access` | `enforce-adapter-import` | `no-unused-content` |
|
|
114
|
+
| --------------- | ----------------------- | ----------------------- | ------------------------- | ------------------------ | ------------------- |
|
|
115
|
+
| `recommended` | warn | error | error | off | off |
|
|
116
|
+
| `strict` | error (+ 비 JSX 리터럴) | error | error | error | off |
|
|
117
|
+
| `contract-only` | off | error | error | off | off |
|
|
118
|
+
|
|
119
|
+
`recommended`는 의도적으로 `no-raw-text`를 `warn`으로 유지합니다. 기존 코드베이스에 적용했을 때 번역되지 않은 모든 문자열이 한 번에 보고되어 첫날부터 빌드가 중단되는 것을 방지하기 위함입니다.
|
|
120
|
+
|
|
121
|
+
`enforce-adapter-import`는 기본적으로 꺼져 있습니다. 필요한 경우 명시적으로 활성화하세요.
|
|
122
|
+
|
|
123
|
+
`no-unused-content`는 `strict`를 포함한 모든 사전 설정에서 꺼져 있습니다. 이 규칙은 Intlayer 설정을 읽고 디스크의 소스 파일을 직접 순회하므로, 사전 설정에 의해 자동으로 켜지기보다는 신중한 선택에 따라 활성화해야 합니다.
|
|
124
|
+
|
|
125
|
+
## 규칙
|
|
126
|
+
|
|
127
|
+
### `no-raw-text`
|
|
128
|
+
|
|
129
|
+
사전에 선언되지 않은 사용자 대면 텍스트를 보고합니다. `intlayer extract`와 동일한 감지 방식을 사용하므로 브랜드 이름, CSS 클래스 및 기술적 식별자는 무시됩니다.
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
// ✗ 보고됨
|
|
133
|
+
<h1>Welcome to our documentation</h1>
|
|
134
|
+
<input placeholder="Enter your email address" />
|
|
135
|
+
|
|
136
|
+
// ✓ 정상
|
|
137
|
+
const { title } = useIntlayer("home");
|
|
138
|
+
<h1>{title}</h1>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
콘텐츠 선언 파일(`*.content.ts`, …)은 제외됩니다.
|
|
142
|
+
|
|
143
|
+
파일 전체를 한 번에 수정하려면 `npx intlayer extract`를 실행하여 컴파일러가 문자열을 사전으로 이동하도록 하세요.
|
|
144
|
+
|
|
145
|
+
**옵션**
|
|
146
|
+
|
|
147
|
+
```javascript fileName="eslint.config.mjs" codeFormat="esm"
|
|
148
|
+
{
|
|
149
|
+
"intlayer/no-raw-text": [
|
|
150
|
+
"warn",
|
|
151
|
+
{
|
|
152
|
+
// 사용자 대면 텍스트가 값인 속성
|
|
153
|
+
// 기본값: title, placeholder, alt, aria-label, label
|
|
154
|
+
attributes: ["title", "placeholder", "alt", "aria-label", "label"],
|
|
155
|
+
|
|
156
|
+
// 콘텐츠가 사용자 대면 텍스트가 아닌 요소
|
|
157
|
+
// 기본값: code, pre, script, style
|
|
158
|
+
ignoreElements: ["code", "pre", "script", "style"],
|
|
159
|
+
|
|
160
|
+
// 보고하지 않을 텍스트의 정규식
|
|
161
|
+
ignorePatterns: ["^Powered by"],
|
|
162
|
+
|
|
163
|
+
// 마크업 외부의 문자열 리터럴도 보고할지 여부. 기본값: false
|
|
164
|
+
includeStringLiterals: false,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `static-dictionary-key`
|
|
171
|
+
|
|
172
|
+
사전 키가 반드시 문자열 리터럴이어야 합니다.
|
|
173
|
+
|
|
174
|
+
컴파일러는 호출 위치에서 키를 직접 읽을 수 있을 때만 사전을 사전 로드(pre-load)할 수 있습니다. 계산된 키를 사용하면 최적화를 자동으로 건너뛰고 모든 사전을 번들에 포함합니다.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// ✗ 보고됨
|
|
178
|
+
useIntlayer(dictionaryKey);
|
|
179
|
+
useIntlayer(`home-${suffix}`);
|
|
180
|
+
getTranslations({ namespace: page });
|
|
181
|
+
|
|
182
|
+
// ✗ 변수는 리터럴이 아닙니다
|
|
183
|
+
const key = "home";
|
|
184
|
+
useIntlayer(key);
|
|
185
|
+
|
|
186
|
+
// ✓ 정상
|
|
187
|
+
useIntlayer("home");
|
|
188
|
+
getTranslations({ namespace: "home" });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
이는 `useIntlayer`, `getIntlayer` 및 모든 호환 어댑터(`useTranslation`, `useTranslations`, `formatMessage`, `<FormattedMessage id>`, `<Trans i18nKey>`, …)에 적용됩니다.
|
|
192
|
+
|
|
193
|
+
### `no-dynamic-field-access`
|
|
194
|
+
|
|
195
|
+
사전에서 읽는 필드가 정적으로 알려져 있어야 합니다.
|
|
196
|
+
|
|
197
|
+
컴파일러는 사용되지 않는 것으로 판단되는 필드를 제거합니다. 동적 접근은 컴파일러가 감지할 수 없으므로 런타임에 읽기 작업이 `undefined`를 반환할 수 있습니다.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// ✗ 보고됨
|
|
201
|
+
const content = useIntlayer("home");
|
|
202
|
+
content[fieldName];
|
|
203
|
+
|
|
204
|
+
const t = useTranslations("home");
|
|
205
|
+
t(messageKey);
|
|
206
|
+
|
|
207
|
+
// ✓ 정상
|
|
208
|
+
content.title;
|
|
209
|
+
content["title"];
|
|
210
|
+
content.items[0];
|
|
211
|
+
t("hero.title");
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `enforce-adapter-import`
|
|
215
|
+
|
|
216
|
+
원본 패키지 대신 `@intlayer/*` 호환 어댑터의 사용을 권장합니다. 원본 패키지는 번들러 별칭이 설정된 경우에만 Intlayer로 확인되지만, 어댑터는 항상 확인됩니다. `--fix`로 자동 수정할 수 있습니다.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// ✗ 보고됨
|
|
220
|
+
import { useTranslation } from "react-i18next";
|
|
221
|
+
import { getTranslations } from "next-intl/server";
|
|
222
|
+
|
|
223
|
+
// ✓ 정상
|
|
224
|
+
import { useTranslation } from "@intlayer/react-i18next";
|
|
225
|
+
import { getTranslations } from "@intlayer/next-intl/server";
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `no-unused-content`
|
|
229
|
+
|
|
230
|
+
**기본적으로 꺼져 있습니다.** 프로젝트 내에서 아무 곳에서도 읽지 않는 콘텐츠와 여러 위치에서 선언된 사전 키를 보고합니다.
|
|
231
|
+
|
|
232
|
+
```typescript fileName="src/home.content.ts"
|
|
233
|
+
export default {
|
|
234
|
+
key: "home", // ✗ 프로젝트 내 어떤 호출자도 "home"을 요청하지 않을 때 보고됨
|
|
235
|
+
content: {
|
|
236
|
+
title: t({ ko: "제목", en: "Title" }),
|
|
237
|
+
|
|
238
|
+
// ✗ `hero`를 읽는 곳이 없을 때 보고됨
|
|
239
|
+
hero: {
|
|
240
|
+
subtitle: t({ ko: "소제목", en: "Subtitle" }),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
다른 규칙과 달리 이 규칙은 현재 파일 하나만으로 판단할 수 없습니다. 필드 사용 여부는 전체 프로젝트와의 관계에서만 파악할 수 있기 때문입니다. 린트 실행 시 첫 번째 콘텐츠 선언을 만났을 때 Intlayer 설정을 로드하고, 해당 설정에 선언된 소스 파일(`build.traversePattern`, `compiler.transformPattern`)을 수집한 후 `@intlayer/lsp` 및 VS Code 확장의 "미사용" 취소선을 지원하는 동일한 사용량 분석기를 실행합니다. 결과는 `cacheTtl` 밀리초 동안 캐시되므로 파일마다 검사하지 않고 1회 실행당 한 번만 검사를 수행합니다.
|
|
247
|
+
|
|
248
|
+
**옵션**
|
|
249
|
+
|
|
250
|
+
```javascript fileName="eslint.config.mjs" codeFormat="esm"
|
|
251
|
+
{
|
|
252
|
+
"intlayer/no-unused-content": [
|
|
253
|
+
"warn",
|
|
254
|
+
{
|
|
255
|
+
// 아무 곳에서도 참조하지 않는 사전 키 보고. 기본값: true
|
|
256
|
+
reportUnusedDictionaries: true,
|
|
257
|
+
|
|
258
|
+
// 아무 곳에서도 읽지 않는 콘텐츠 필드 보고. 기본값: true
|
|
259
|
+
reportUnusedFields: true,
|
|
260
|
+
|
|
261
|
+
// 여러 위치에 선언된 중복 키 보고. 기본값: true
|
|
262
|
+
reportDuplicateKeys: true,
|
|
263
|
+
|
|
264
|
+
// 보고하지 않을 필드 경로의 정규식
|
|
265
|
+
ignoreFields: ["^meta"],
|
|
266
|
+
|
|
267
|
+
// 검사가 시작되는 프로젝트 루트. 기본값: ESLint 작업 디렉터리
|
|
268
|
+
baseDir: process.cwd(),
|
|
269
|
+
|
|
270
|
+
// 한 번의 프로젝트 검사 결과를 재사용하는 시간(ms). 기본값: 30000
|
|
271
|
+
cacheTtl: 30000,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
오랫동안 실행되는 에디터 서버에서 린트를 수행하며 변경 사항을 더 빨리 반영하고 싶을 때는 `cacheTtl`을 줄이세요. 모노레포에서 단일 린트 실행이 여러 Intlayer 프로젝트에 걸쳐 있을 때는 `baseDir`을 설정하세요.
|
|
278
|
+
|
|
279
|
+
> **침묵을 우선합니다.** 여기서 거짓 양성(false positive)이 발생하면 필요한 번역이 삭제될 수 있으므로, 분석기가 추적할 수 없는 방식으로 사전을 소비할 때는 아무것도 보고하지 않습니다: 콘텐츠 객체 전체를 그대로 전달, 객체에서 바인딩된 번역 함수(`const t = useTranslations("home")`), 직접 가져오기를 통한 선언 접근(`useDictionary(myDictionary)`), 다른 사전에서의 `nest()`, 또는 스프레드 연산자로 불완전해진 필드 목록 등입니다. 단일 파일 컴포넌트(`.vue`, `.svelte`, `.astro`)는 스크립트 블록이 여기서 파싱되지 않으므로 언급된 사전의 모든 필드를 사용하는 것으로 간주됩니다.
|
|
280
|
+
|
|
281
|
+
`reportDuplicateKeys`는 빌드 시 `.intlayer/`에 기록되는 병합되지 않은 사전을 읽으므로 프로젝트가 최소 한 번 빌드될 때까지는 동작하지 않습니다. 키를 공유하는 두 선언은 병합되며 이는 올바른 패턴입니다. 다만 양쪽에 정의된 필드가 조용히 둘 중 하나의 값만 유지하기 때문에 이 보고 기능이 제공됩니다.
|
|
282
|
+
|
|
283
|
+
분석기는 ESM으로 제공되는 `@intlayer/lsp`에서 로드됩니다. 따라서 이 규칙은 ES 모듈을 `require()`할 수 있는 Node 버전(Node 20.19+ 또는 22.12+)이 필요합니다. 이전 버전에서는 린트 실행을 실패시키는 대신 아무것도 보고하지 않습니다.
|
|
284
|
+
|
|
285
|
+
## 프레임워크
|
|
286
|
+
|
|
287
|
+
모든 규칙은 Vue, Svelte 및 Angular 템플릿 내부를 포함하여 모든 Intlayer 통합 환경에서 작동합니다. ESLint에 각 파일 형식을 읽을 파서만 지정해 주면 됩니다.
|
|
288
|
+
|
|
289
|
+
| 프레임워크 | 파일 | 파서 |
|
|
290
|
+
| ------------------------- | ----------------- | --------------------------------- |
|
|
291
|
+
| React, Preact, Solid, Lit | `.jsx` `.tsx` | `typescript-eslint` |
|
|
292
|
+
| Next.js | `.jsx` `.tsx` | `typescript-eslint` |
|
|
293
|
+
| Vue, Nuxt | `.vue` | `vue-eslint-parser` |
|
|
294
|
+
| Svelte, SvelteKit | `.svelte` | `svelte-eslint-parser` |
|
|
295
|
+
| Angular | `.ts` | `typescript-eslint` |
|
|
296
|
+
| Angular 템플릿 | `.component.html` | `@angular-eslint/template-parser` |
|
|
297
|
+
| Astro | `.astro` | `astro-eslint-parser` |
|
|
298
|
+
|
|
299
|
+
```javascript fileName="eslint.config.mjs" codeFormat="esm"
|
|
300
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
301
|
+
import tseslint from "typescript-eslint";
|
|
302
|
+
import vueParser from "vue-eslint-parser";
|
|
303
|
+
import svelteParser from "svelte-eslint-parser";
|
|
304
|
+
import angularTemplateParser from "@angular-eslint/template-parser";
|
|
305
|
+
|
|
306
|
+
export default [
|
|
307
|
+
...intlayer.configs.recommended,
|
|
308
|
+
|
|
309
|
+
{
|
|
310
|
+
files: ["**/*.{ts,tsx,jsx}"],
|
|
311
|
+
languageOptions: { parser: tseslint.parser },
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
files: ["**/*.vue"],
|
|
315
|
+
languageOptions: {
|
|
316
|
+
parser: vueParser,
|
|
317
|
+
parserOptions: { parser: tseslint.parser },
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
files: ["**/*.svelte"],
|
|
322
|
+
languageOptions: {
|
|
323
|
+
parser: svelteParser,
|
|
324
|
+
parserOptions: { parser: tseslint.parser },
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
files: ["**/*.component.html"],
|
|
329
|
+
languageOptions: { parser: angularTemplateParser },
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
프로젝트에 필요한 파서만 설치하세요.
|
|
335
|
+
|
|
336
|
+
> **알려진 제한 사항.** Vue 및 Angular 템플릿에서 `{{ content[key] }}`와 같은 표현식은 `no-dynamic-field-access`에 의해 검사되지 않습니다. 스크립트 블록에 작성된 동적 읽기는 정상적으로 감지됩니다.
|
|
@@ -207,7 +207,7 @@ export const ComponentExample = () => {
|
|
|
207
207
|
이러한 방식을 적용하면 다음과 같은 혁신적인 효과를 얻을 수 있습니다:
|
|
208
208
|
|
|
209
209
|
1. **개발 생산성의 대폭 향상**
|
|
210
|
-
- `.content.{
|
|
210
|
+
- `.content.{ts|js|mjs|cjs|json|tsx|jsx|md|mdx|yaml|yml}` 파일 선언을 돕는 VSCode 공식 확장 프로그램 지원
|
|
211
211
|
- IDE의 AI 자동완성 도구(예: GitHub Copilot)가 문맥을 정확히 파악하여 콘텐츠 선언을 도와 복사/붙여넣기 수작업이 극적으로 축소됨
|
|
212
212
|
|
|
213
213
|
2. **청결한 코드베이스 유지**
|
|
@@ -231,27 +231,27 @@ export const ComponentExample = () => {
|
|
|
231
231
|
|
|
232
232
|
## Intlayer의 추가 기능
|
|
233
233
|
|
|
234
|
-
| 기능 | 설명
|
|
235
|
-
| ------------------------------------------------------------------------------------------------------------------------- |
|
|
236
|
-
|  | **크로스 프레임워크 범용 지원**<br><br>Intlayer는 Next.js, React, Vite, Vue.js, Nuxt, Preact, Express 등 다양한 대중적인 프레임워크 및 라이브러리와 완벽하게 호환됩니다.
|
|
237
|
-
|  | **JavaScript 구문 기반의 동적 콘텐츠 관리**<br><br>JavaScript/TypeScript의 높은 유연성을 활용하여 복잡하고 세련된 콘텐츠 구조를 효율적으로 구성할 수 있습니다. <br><br> - [콘텐츠 선언 가이드](https://intlayer.org/doc/concept/content)
|
|
238
|
-
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **지능형 컴파일러**<br><br>Intlayer 컴파일러는 프로젝트 소스 코드에서 다국어 콘텐츠를 자동으로 분석 및 추출하여 최적화된 사전 파일을 빌드합니다.<br><br> - [컴파일러 기술 문서](https://intlayer.org/doc/compiler)
|
|
239
|
-
|  | **언어별 독립 선언 파일 기능**<br><br>각 언어별 콘텐츠 선언을 분리함으로써 정밀하고 깔끔하게 파일 구조를 분할 및 확장할 수 있습니다.<br><br> - [언어별 파일 가이드](https://intlayer.org/doc/concept/per-locale-file)
|
|
240
|
-
|  | **엄격한 타입 안전성 보장**<br><br>TypeScript의 강력한 타입 체크를 활용해 휴먼 에러를 완전 차단하고, IDE에서 제공하는 최적의 사전 키 자동완성 힌트를 활용해 보세요.<br><br> - [TypeScript 설정 가이드](https://intlayer.org/doc/environment/vite-and-react#configure-typescript)
|
|
241
|
-
|  | **직관적인 설정 및 시작**<br><br>최소한의 기본 구문 설정으로 앱을 신속히 배포해 보세요. 라우팅, 국제화, 빌드 및 콘텐츠 분석과 관련된 전반적인 제어가 편리합니다. <br><br> - [Next.js 통합 알아보기](https://intlayer.org/doc/environment/nextjs)
|
|
242
|
-
|  | **간편한 콘텐츠 조회**<br><br>자잘한 구문마다 매번 수동으로 `t` 번역 헬퍼를 결합하지 않아도 됩니다. 통합 훅(Hook)을 결합해 필요한 범위의 콘텐츠 딕셔너리를 단번에 인출할 수 있습니다.<br><br> - [React 통합 레퍼런스](https://intlayer.org/doc/environment/create-react-app)
|
|
243
|
-
|  | **일관된 서버 컴포넌트 설계**<br><br>Next.js 서버 컴포넌트(RSC)에 최적화된 아키텍처로, 클라이언트 사이드와 서버 사이드 모두 동일한 훅과 구문 형태를 적용할 수 있어 번거롭게 `t` 함수를 컴포넌트 트리에 수동 전달할 필요가 없습니다. <br><br> - [서버 컴포넌트 가이드](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code)
|
|
244
|
-
|  | **고도로 조직화된 코드베이스**<br><br>코드 설계를 간결하게 분리합니다: 1 기능 컴포넌트 폴더 내에 해당 사전 딕셔너리가 결합되어 높은 가독성을 유도합니다. <br><br> - [Intlayer 작동 개념](https://intlayer.org/doc/concept/how-works-intlayer)
|
|
245
|
-
|  | **강력한 로컬라이즈 라우팅**<br><br>경로 다국어 처리를 기본 탑재하여 Next.js, React, Vite, Vue.js 등을 활용해 복잡하게 얽힌 하위 페이지 주소를 정교하게 분리해 줍니다.<br><br> - [Next.js 통합 가이드](https://intlayer.org/doc/environment/nextjs)
|
|
246
|
-
|  | **Markdown 기본 연동**<br><br>서비스 약관, 법적 공지, 테크니컬 가이드 등 텍스트 서식이 가미된 Markdown 파일 처리를 기본 제공하여, 프론트 코드 내에서 서식 및 메타데이터를 정밀히 매핑할 수 있습니다.<br><br> - [Markdown 활용 가이드](https://intlayer.org/doc/concept/content/file)
|
|
247
|
-
|  | **무료 비주얼 에디터 & 헤드리스 CMS**<br><br>마케터, 기획자, 번역가 등 비개발 협업자가 직관적으로 텍스트를 고칠 수 있는 비주얼 편집 도구와 CMS를 무료 제공합니다. Git 동기화 또는 CMS 원격 결합 방식을 유연하게 설정할 수 있습니다.<br><br> - [비주얼 에디터 문서](https://intlayer.org/doc/concept/editor) <br> - [헤드리스 CMS 문서](https://intlayer.org/doc/concept/cms)
|
|
248
|
-
|  | **Tree-shaking 지원을 통한 초경량 배포**<br><br>빌드 시점에 사용하지 않는 언어와 사전을 완벽히 배포 대상에서 쳐내어 최종 번들 용량을 획기적으로 낮춥니다. 모듈별 레이지 로딩을 원활하게 수행합니다. <br><br> - [빌드 최적화 알아보기](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization)
|
|
249
|
-
|  | **정적 정밀 렌더링(SSG) 최적화**<br><br>정적 생성(Static Rendering) 모듈 작동을 방해하지 않고 부드럽게 작동합니다. <br><br> - [Next.js 정적 빌드](https://intlayer.org/doc/environment/nextjs)
|
|
250
|
-
|  | **원클릭 지능형 AI 번역**<br><br>개발자가 직접 등록한 AI 프로바이더 구성을 바탕으로, CLI 한 번으로 최대 231개 이상의 전 세계 로케일 번역을 자동으로 일괄 적용해 줍니다. <br><br> - [CI/CD 자동 번역](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI 연동](https://intlayer.org/doc/concept/cli) <br> - [자동 채우기](https://intlayer.org/doc/concept/auto-fill)
|
|
251
|
-
|  | **MCP 서버 연동**<br><br>에디터 자동화 표준 프로토콜인 MCP(Model Context Protocol) 서버를 탑재하여, IDE 개발 보조 인공지능이 코드 번역 작업을 훨씬 능동적이고 정확하게 제어하도록 지원합니다. <br><br> - [MCP 서버 정보](https://github.com/aymericzip/intlayer/blob/main/docs/ko/mcp_server.md)
|
|
252
|
-
|  | **VSCode 공식 확장 프로그램**<br><br>사전 딕셔너리 관리, 자동 번역 결합 및 사전 빌드 상태 확인 등을 돕는 전용 에디터 확장을 연동해 보세요. <br><br> - [에디터 확장 프로그램](https://intlayer.org/doc/vs-code-extension)
|
|
253
|
-
|  | **높은 상호 운용성**<br><br>기존 react-i18next, next-i18next, next-intl, react-intl 등 기존 모듈 규격에서 손쉽게 마이그레이션하거나 공존할 수 있는 통합 API를 구축했습니다. <br><br> - [react-intl 연동](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [next-intl 연동](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [next-i18next 연동](https://intlayer.org/blog/intlayer-with-next-i18next) |
|
|
254
|
-
| 번역 누락 테스트(CLI/CI) | ✅ CLI: npx intlayer content test (CI 친화적인 자동 진단)
|
|
234
|
+
| 기능 | 설명 |
|
|
235
|
+
| ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
236
|
+
|  | **크로스 프레임워크 범용 지원**<br><br>Intlayer는 Next.js, React, Vite, Vue.js, Nuxt, Preact, Express 등 다양한 대중적인 프레임워크 및 라이브러리와 완벽하게 호환됩니다. |
|
|
237
|
+
|  | **JavaScript 구문 기반의 동적 콘텐츠 관리**<br><br>JavaScript/TypeScript의 높은 유연성을 활용하여 복잡하고 세련된 콘텐츠 구조를 효율적으로 구성할 수 있습니다. <br><br> - [콘텐츠 선언 가이드](https://intlayer.org/doc/concept/content) |
|
|
238
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **지능형 컴파일러**<br><br>Intlayer 컴파일러는 프로젝트 소스 코드에서 다국어 콘텐츠를 자동으로 분석 및 추출하여 최적화된 사전 파일을 빌드합니다.<br><br> - [컴파일러 기술 문서](https://intlayer.org/doc/compiler) |
|
|
239
|
+
|  | **언어별 독립 선언 파일 기능**<br><br>각 언어별 콘텐츠 선언을 분리함으로써 정밀하고 깔끔하게 파일 구조를 분할 및 확장할 수 있습니다.<br><br> - [언어별 파일 가이드](https://intlayer.org/doc/concept/per-locale-file) |
|
|
240
|
+
|  | **엄격한 타입 안전성 보장**<br><br>TypeScript의 강력한 타입 체크를 활용해 휴먼 에러를 완전 차단하고, IDE에서 제공하는 최적의 사전 키 자동완성 힌트를 활용해 보세요.<br><br> - [TypeScript 설정 가이드](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
|
|
241
|
+
|  | **직관적인 설정 및 시작**<br><br>최소한의 기본 구문 설정으로 앱을 신속히 배포해 보세요. 라우팅, 국제화, 빌드 및 콘텐츠 분석과 관련된 전반적인 제어가 편리합니다. <br><br> - [Next.js 통합 알아보기](https://intlayer.org/doc/environment/nextjs) |
|
|
242
|
+
|  | **간편한 콘텐츠 조회**<br><br>자잘한 구문마다 매번 수동으로 `t` 번역 헬퍼를 결합하지 않아도 됩니다. 통합 훅(Hook)을 결합해 필요한 범위의 콘텐츠 딕셔너리를 단번에 인출할 수 있습니다.<br><br> - [React 통합 레퍼런스](https://intlayer.org/doc/environment/create-react-app) |
|
|
243
|
+
|  | **일관된 서버 컴포넌트 설계**<br><br>Next.js 서버 컴포넌트(RSC)에 최적화된 아키텍처로, 클라이언트 사이드와 서버 사이드 모두 동일한 훅과 구문 형태를 적용할 수 있어 번거롭게 `t` 함수를 컴포넌트 트리에 수동 전달할 필요가 없습니다. <br><br> - [서버 컴포넌트 가이드](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
|
|
244
|
+
|  | **고도로 조직화된 코드베이스**<br><br>코드 설계를 간결하게 분리합니다: 1 기능 컴포넌트 폴더 내에 해당 사전 딕셔너리가 결합되어 높은 가독성을 유도합니다. <br><br> - [Intlayer 작동 개념](https://intlayer.org/doc/concept/how-works-intlayer) |
|
|
245
|
+
|  | **강력한 로컬라이즈 라우팅**<br><br>경로 다국어 처리를 기본 탑재하여 Next.js, React, Vite, Vue.js 등을 활용해 복잡하게 얽힌 하위 페이지 주소를 정교하게 분리해 줍니다.<br><br> - [Next.js 통합 가이드](https://intlayer.org/doc/environment/nextjs) |
|
|
246
|
+
|  | **Markdown 기본 연동**<br><br>서비스 약관, 법적 공지, 테크니컬 가이드 등 텍스트 서식이 가미된 Markdown 파일 처리를 기본 제공하여, 프론트 코드 내에서 서식 및 메타데이터를 정밀히 매핑할 수 있습니다.<br><br> - [Markdown 활용 가이드](https://intlayer.org/doc/concept/content/file) |
|
|
247
|
+
|  | **무료 비주얼 에디터 & 헤드리스 CMS**<br><br>마케터, 기획자, 번역가 등 비개발 협업자가 직관적으로 텍스트를 고칠 수 있는 비주얼 편집 도구와 CMS를 무료 제공합니다. Git 동기화 또는 CMS 원격 결합 방식을 유연하게 설정할 수 있습니다.<br><br> - [비주얼 에디터 문서](https://intlayer.org/doc/concept/editor) <br> - [헤드리스 CMS 문서](https://intlayer.org/doc/concept/cms) |
|
|
248
|
+
|  | **Tree-shaking 지원을 통한 초경량 배포**<br><br>빌드 시점에 사용하지 않는 언어와 사전을 완벽히 배포 대상에서 쳐내어 최종 번들 용량을 획기적으로 낮춥니다. 모듈별 레이지 로딩을 원활하게 수행합니다. <br><br> - [빌드 최적화 알아보기](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
|
|
249
|
+
|  | **정적 정밀 렌더링(SSG) 최적화**<br><br>정적 생성(Static Rendering) 모듈 작동을 방해하지 않고 부드럽게 작동합니다. <br><br> - [Next.js 정적 빌드](https://intlayer.org/doc/environment/nextjs) |
|
|
250
|
+
|  | **원클릭 지능형 AI 번역**<br><br>개발자가 직접 등록한 AI 프로바이더 구성을 바탕으로, CLI 한 번으로 최대 231개 이상의 전 세계 로케일 번역을 자동으로 일괄 적용해 줍니다. <br><br> - [CI/CD 자동 번역](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI 연동](https://intlayer.org/doc/concept/cli) <br> - [자동 채우기](https://intlayer.org/doc/concept/auto-fill) |
|
|
251
|
+
|  | **MCP 서버 연동**<br><br>에디터 자동화 표준 프로토콜인 MCP(Model Context Protocol) 서버를 탑재하여, IDE 개발 보조 인공지능이 코드 번역 작업을 훨씬 능동적이고 정확하게 제어하도록 지원합니다. <br><br> - [MCP 서버 정보](https://github.com/aymericzip/intlayer/blob/main/docs/ko/mcp_server.md) |
|
|
252
|
+
|  | **VSCode 공식 확장 프로그램**<br><br>사전 딕셔너리 관리, 자동 번역 결합 및 사전 빌드 상태 확인 등을 돕는 전용 에디터 확장을 연동해 보세요. <br><br> - [에디터 확장 프로그램](https://intlayer.org/doc/vs-code-extension) |
|
|
253
|
+
|  | **높은 상호 운용성**<br><br>기존 react-i18next, next-i18next, next-intl, react-intl 등 기존 모듈 규격에서 손쉽게 마이그레이션하거나 공존할 수 있는 통합 API를 구축했습니다. <br><br> - [react-intl 연동](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [next-intl 연동](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [next-i18next 연동](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer 호환 어댑터](https://intlayer.org/doc/compatibility) |
|
|
254
|
+
| 번역 누락 테스트(CLI/CI) | ✅ CLI: npx intlayer content test (CI 친화적인 자동 진단) |
|
|
255
255
|
|
|
256
256
|
## Intlayer와 다른 솔루션 비교
|
|
257
257
|
|
|
@@ -290,3 +290,5 @@ GitHub Star 수는 프로젝트의 인지도, 커뮤니티의 신뢰도 및 장
|
|
|
290
290
|
`intlayer`는 기존의 `react-intl`, `react-i18next`, `next-intl`, `next-i18next` 및 `vue-i18n` 사전 네임스페이스들을 동시에 손쉽게 지배하고 가공하도록 지원합니다.
|
|
291
291
|
|
|
292
292
|
`intlayer` 문법 형태로 다국어를 간편히 선언만 해두면, intlayer가 번거롭고 복잡한 기존 프레임워크 규격(예: `/messages/{{locale}}/{{namespace}}.json`)에 맞춰 빌드 타임에 자동으로 사전 파일을 추출 및 변환해 줍니다.
|
|
293
|
+
|
|
294
|
+
현재 사용 중인 i18n 라이브러리의 API를 그대로 유지하고 싶다면, `intlayer`는 **호환 어댑터(compat adapters)** 도 제공합니다. `react-i18next`, `next-intl`, `react-intl`, `vue-i18n` 등과 완전히 동일한 API를 노출하지만, 실제 콘텐츠는 Intlayer 사전에서 제공되는 패키지입니다. 덕분에 코드를 다시 작성하지 않고 점진적으로 마이그레이션할 수 있습니다. [호환 어댑터 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/compat/index.md)를 참고하세요.
|
|
@@ -266,10 +266,12 @@ export default preview;
|
|
|
266
266
|
|
|
267
267
|
> `locale` 값은 `intlayer.config.ts`에 선언된 로케일과 일치해야 합니다.
|
|
268
268
|
|
|
269
|
+
</Step>
|
|
270
|
+
</Steps>
|
|
269
271
|
</Tab>
|
|
270
272
|
<Tab value="Webpack Setup">
|
|
271
273
|
|
|
272
|
-
|
|
274
|
+
<Steps>
|
|
273
275
|
|
|
274
276
|
<Step number={1} title="종속성 설치">
|
|
275
277
|
|
|
@@ -391,15 +393,13 @@ const preview: Preview = {
|
|
|
391
393
|
export default preview;
|
|
392
394
|
```
|
|
393
395
|
|
|
396
|
+
</Step>
|
|
397
|
+
</Steps>
|
|
394
398
|
</Tab>
|
|
395
399
|
</Tabs>
|
|
396
400
|
|
|
397
401
|
---
|
|
398
402
|
|
|
399
|
-
</Step>
|
|
400
|
-
|
|
401
|
-
</Steps>
|
|
402
|
-
|
|
403
403
|
## 콘텐츠 선언
|
|
404
404
|
|
|
405
405
|
각 컴포넌트 옆에 `*.content.ts` 파일을 생성합니다. Intlayer는 컴파일 중에 이를 자동으로 감지합니다.
|
|
@@ -404,7 +404,7 @@ export const getLocale = (event: RequestEvent): Locale => {
|
|
|
404
404
|
};
|
|
405
405
|
```
|
|
406
406
|
|
|
407
|
-
> `getLocaleFromStorage`는 구성에 따라 헤더 또는 쿠키에서 로케일을 확인합니다. 자세한 내용은 [Configuration](https://intlayer.org/doc/configuration) 문서를 참조하세요.
|
|
407
|
+
> `getLocaleFromStorage`는 구성에 따라 헤더 또는 쿠키에서 로케일을 확인합니다. 자세한 내용은 [Configuration](https://intlayer.org/doc/concept/configuration) 문서를 참조하세요.
|
|
408
408
|
|
|
409
409
|
> `localeDetector` 함수는 `Accept-Language` 헤더를 처리하여 가장 적합한 로케일을 반환합니다.
|
|
410
410
|
|
|
@@ -254,19 +254,21 @@ import {
|
|
|
254
254
|
HeadContent,
|
|
255
255
|
Scripts,
|
|
256
256
|
createRootRouteWithContext,
|
|
257
|
+
getRouteApi,
|
|
257
258
|
} from "@tanstack/solid-router";
|
|
258
259
|
import { HydrationScript } from "solid-js/web";
|
|
259
260
|
import { Suspense, type ParentComponent } from "solid-js";
|
|
260
261
|
import { IntlayerProvider } from "solid-intlayer";
|
|
261
262
|
import { defaultLocale, getHTMLTextDir } from "intlayer";
|
|
262
|
-
|
|
263
|
+
|
|
264
|
+
const localeRoute = getRouteApi("/{-$locale}");
|
|
263
265
|
|
|
264
266
|
export const Route = createRootRouteWithContext()({
|
|
265
267
|
shellComponent: RootComponent,
|
|
266
268
|
});
|
|
267
269
|
|
|
268
270
|
const RootComponent: ParentComponent = (props) => {
|
|
269
|
-
const params =
|
|
271
|
+
const params = localeRoute.useParams();
|
|
270
272
|
const locale = params()?.locale ?? defaultLocale;
|
|
271
273
|
|
|
272
274
|
return (
|
|
@@ -551,7 +553,7 @@ export default LocaleSwitcher;
|
|
|
551
553
|
|
|
552
554
|
```tsx fileName="src/routes/__root.tsx"
|
|
553
555
|
const RootComponent: ParentComponent = (props) => {
|
|
554
|
-
const params =
|
|
556
|
+
const params = localeRoute.useParams();
|
|
555
557
|
const locale = params()?.locale ?? defaultLocale;
|
|
556
558
|
|
|
557
559
|
return (
|