@intlayer/docs 7.3.15 → 7.5.0-canary.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_i18next.md +2 -0
- package/blog/ar/intlayer_with_next-i18next.md +2 -0
- package/blog/ar/intlayer_with_next-intl.md +2 -0
- package/blog/ar/intlayer_with_react-i18next.md +2 -0
- package/blog/ar/intlayer_with_react-intl.md +2 -0
- package/blog/ar/intlayer_with_vue-i18n.md +2 -0
- package/blog/de/intlayer_with_i18next.md +2 -0
- package/blog/de/intlayer_with_next-i18next.md +1 -0
- package/blog/de/intlayer_with_next-intl.md +2 -0
- package/blog/de/intlayer_with_react-i18next.md +2 -0
- package/blog/de/intlayer_with_react-intl.md +2 -0
- package/blog/de/intlayer_with_vue-i18n.md +2 -0
- package/blog/en/intlayer_with_i18next.md +6 -0
- package/blog/en/intlayer_with_next-i18next.md +3 -0
- package/blog/en/intlayer_with_next-intl.md +3 -0
- package/blog/en/intlayer_with_react-i18next.md +3 -0
- package/blog/en/intlayer_with_react-intl.md +3 -0
- package/blog/en/intlayer_with_vue-i18n.md +3 -0
- package/blog/en-GB/intlayer_with_i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-intl.md +2 -0
- package/blog/en-GB/intlayer_with_react-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_react-intl.md +2 -0
- package/blog/en-GB/intlayer_with_vue-i18n.md +2 -0
- package/blog/es/intlayer_with_i18next.md +2 -0
- package/blog/es/intlayer_with_next-i18next.md +2 -0
- package/blog/es/intlayer_with_next-intl.md +2 -0
- package/blog/es/intlayer_with_react-i18next.md +2 -0
- package/blog/es/intlayer_with_react-intl.md +2 -0
- package/blog/es/intlayer_with_vue-i18n.md +2 -0
- package/blog/fr/intlayer_with_i18next.md +2 -0
- package/blog/fr/intlayer_with_next-i18next.md +2 -0
- package/blog/fr/intlayer_with_next-intl.md +2 -0
- package/blog/fr/intlayer_with_react-i18next.md +2 -0
- package/blog/fr/intlayer_with_react-intl.md +2 -0
- package/blog/fr/intlayer_with_vue-i18n.md +2 -0
- package/blog/hi/intlayer_with_i18next.md +2 -0
- package/blog/hi/intlayer_with_next-i18next.md +2 -0
- package/blog/hi/intlayer_with_next-intl.md +2 -0
- package/blog/hi/intlayer_with_react-i18next.md +2 -0
- package/blog/hi/intlayer_with_react-intl.md +2 -0
- package/blog/hi/intlayer_with_vue-i18n.md +2 -0
- package/blog/id/intlayer_with_i18next.md +2 -0
- package/blog/id/intlayer_with_next-i18next.md +2 -0
- package/blog/id/intlayer_with_next-intl.md +2 -0
- package/blog/id/intlayer_with_react-i18next.md +2 -0
- package/blog/id/intlayer_with_react-intl.md +2 -0
- package/blog/id/intlayer_with_vue-i18n.md +2 -0
- package/blog/it/intlayer_with_i18next.md +2 -0
- package/blog/it/intlayer_with_next-i18next.md +2 -0
- package/blog/it/intlayer_with_next-intl.md +2 -0
- package/blog/it/intlayer_with_react-i18next.md +2 -0
- package/blog/it/intlayer_with_react-intl.md +2 -0
- package/blog/it/intlayer_with_vue-i18n.md +2 -0
- package/blog/ja/intlayer_with_i18next.md +2 -0
- package/blog/ja/intlayer_with_next-i18next.md +1 -0
- package/blog/ja/intlayer_with_next-intl.md +2 -0
- package/blog/ja/intlayer_with_react-i18next.md +2 -0
- package/blog/ja/intlayer_with_react-intl.md +2 -0
- package/blog/ja/intlayer_with_vue-i18n.md +2 -0
- package/blog/ko/intlayer_with_i18next.md +2 -0
- package/blog/ko/intlayer_with_next-i18next.md +2 -0
- package/blog/ko/intlayer_with_next-intl.md +2 -0
- package/blog/ko/intlayer_with_react-i18next.md +2 -0
- package/blog/ko/intlayer_with_react-intl.md +2 -0
- package/blog/ko/intlayer_with_vue-i18n.md +2 -0
- package/blog/pl/intlayer_with_i18next.md +2 -0
- package/blog/pl/intlayer_with_next-i18next.md +2 -0
- package/blog/pl/intlayer_with_next-intl.md +2 -0
- package/blog/pl/intlayer_with_react-i18next.md +2 -0
- package/blog/pl/intlayer_with_react-intl.md +2 -0
- package/blog/pl/intlayer_with_vue-i18n.md +2 -0
- package/blog/pt/intlayer_with_i18next.md +2 -0
- package/blog/pt/intlayer_with_next-i18next.md +2 -0
- package/blog/pt/intlayer_with_next-intl.md +2 -0
- package/blog/pt/intlayer_with_react-i18next.md +2 -0
- package/blog/pt/intlayer_with_react-intl.md +2 -0
- package/blog/pt/intlayer_with_vue-i18n.md +2 -0
- package/blog/ru/intlayer_with_i18next.md +2 -0
- package/blog/ru/intlayer_with_next-i18next.md +2 -0
- package/blog/ru/intlayer_with_next-intl.md +2 -0
- package/blog/ru/intlayer_with_react-i18next.md +2 -0
- package/blog/ru/intlayer_with_react-intl.md +2 -0
- package/blog/ru/intlayer_with_vue-i18n.md +2 -0
- package/blog/tr/intlayer_with_i18next.md +2 -0
- package/blog/tr/intlayer_with_next-i18next.md +2 -0
- package/blog/tr/intlayer_with_next-intl.md +2 -0
- package/blog/tr/intlayer_with_react-i18next.md +2 -0
- package/blog/tr/intlayer_with_react-intl.md +2 -0
- package/blog/tr/intlayer_with_vue-i18n.md +2 -0
- package/blog/vi/intlayer_with_i18next.md +2 -0
- package/blog/vi/intlayer_with_next-i18next.md +2 -0
- package/blog/vi/intlayer_with_next-intl.md +2 -0
- package/blog/vi/intlayer_with_react-i18next.md +2 -0
- package/blog/vi/intlayer_with_react-intl.md +2 -0
- package/blog/vi/intlayer_with_vue-i18n.md +2 -0
- package/blog/zh/intlayer_with_i18next.md +2 -0
- package/blog/zh/intlayer_with_next-i18next.md +2 -0
- package/blog/zh/intlayer_with_next-intl.md +2 -0
- package/blog/zh/intlayer_with_react-i18next.md +2 -0
- package/blog/zh/intlayer_with_react-intl.md +2 -0
- package/blog/zh/intlayer_with_vue-i18n.md +2 -0
- package/docs/ar/dictionary/content_file.md +24 -1
- package/docs/ar/intlayer_with_astro.md +1 -1
- package/docs/ar/intlayer_with_express.md +1 -1
- package/docs/ar/intlayer_with_nestjs.md +1 -1
- package/docs/ar/intlayer_with_next-i18next.md +1 -0
- package/docs/ar/intlayer_with_next-intl.md +1 -0
- package/docs/ar/intlayer_with_tanstack.md +122 -3
- package/docs/ar/plugins/sync-json.md +27 -2
- package/docs/de/dictionary/content_file.md +24 -1
- package/docs/de/intlayer_with_astro.md +1 -1
- package/docs/de/intlayer_with_express.md +1 -1
- package/docs/de/intlayer_with_nestjs.md +1 -1
- package/docs/de/intlayer_with_next-i18next.md +1 -0
- package/docs/de/intlayer_with_next-intl.md +1 -0
- package/docs/de/intlayer_with_tanstack.md +122 -3
- package/docs/de/plugins/sync-json.md +27 -2
- package/docs/en/dictionary/content_file.md +24 -1
- package/docs/en/intlayer_with_astro.md +1 -1
- package/docs/en/intlayer_with_express.md +1 -1
- package/docs/en/intlayer_with_nestjs.md +1 -2
- package/docs/en/intlayer_with_next-i18next.md +1 -0
- package/docs/en/intlayer_with_next-intl.md +1 -0
- package/docs/en/intlayer_with_tanstack.md +120 -1
- package/docs/en/plugins/sync-json.md +53 -2
- package/docs/en-GB/dictionary/content_file.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +1 -1
- package/docs/en-GB/intlayer_with_express.md +1 -1
- package/docs/en-GB/intlayer_with_nestjs.md +1 -1
- package/docs/en-GB/intlayer_with_next-i18next.md +1 -0
- package/docs/en-GB/intlayer_with_next-intl.md +1 -0
- package/docs/en-GB/intlayer_with_tanstack.md +121 -2
- package/docs/en-GB/plugins/sync-json.md +26 -1
- package/docs/es/dictionary/content_file.md +24 -1
- package/docs/es/intlayer_with_astro.md +1 -1
- package/docs/es/intlayer_with_express.md +1 -1
- package/docs/es/intlayer_with_nestjs.md +1 -1
- package/docs/es/intlayer_with_next-i18next.md +1 -0
- package/docs/es/intlayer_with_next-intl.md +1 -0
- package/docs/es/intlayer_with_tanstack.md +122 -3
- package/docs/es/plugins/sync-json.md +27 -2
- package/docs/fr/dictionary/content_file.md +24 -1
- package/docs/fr/intlayer_with_astro.md +1 -1
- package/docs/fr/intlayer_with_express.md +1 -1
- package/docs/fr/intlayer_with_nestjs.md +1 -1
- package/docs/fr/intlayer_with_next-i18next.md +1 -0
- package/docs/fr/intlayer_with_next-intl.md +1 -0
- package/docs/fr/intlayer_with_tanstack.md +122 -3
- package/docs/fr/plugins/sync-json.md +27 -2
- package/docs/hi/dictionary/content_file.md +24 -1
- package/docs/hi/intlayer_with_astro.md +1 -1
- package/docs/hi/intlayer_with_express.md +1 -1
- package/docs/hi/intlayer_with_nestjs.md +1 -1
- package/docs/hi/intlayer_with_next-i18next.md +1 -0
- package/docs/hi/intlayer_with_next-intl.md +1 -0
- package/docs/hi/intlayer_with_tanstack.md +122 -3
- package/docs/hi/plugins/sync-json.md +27 -2
- package/docs/id/dictionary/content_file.md +24 -1
- package/docs/id/intlayer_with_astro.md +1 -1
- package/docs/id/intlayer_with_express.md +1 -1
- package/docs/id/intlayer_with_nestjs.md +1 -1
- package/docs/id/intlayer_with_next-i18next.md +1 -0
- package/docs/id/intlayer_with_next-intl.md +1 -0
- package/docs/id/intlayer_with_tanstack.md +122 -3
- package/docs/id/plugins/sync-json.md +27 -2
- package/docs/it/dictionary/content_file.md +24 -1
- package/docs/it/intlayer_with_astro.md +1 -1
- package/docs/it/intlayer_with_express.md +1 -1
- package/docs/it/intlayer_with_nestjs.md +1 -1
- package/docs/it/intlayer_with_next-i18next.md +1 -0
- package/docs/it/intlayer_with_next-intl.md +1 -0
- package/docs/it/intlayer_with_tanstack.md +122 -3
- package/docs/it/plugins/sync-json.md +27 -2
- package/docs/ja/dictionary/content_file.md +24 -1
- package/docs/ja/intlayer_with_astro.md +1 -1
- package/docs/ja/intlayer_with_express.md +1 -1
- package/docs/ja/intlayer_with_nestjs.md +1 -1
- package/docs/ja/intlayer_with_next-i18next.md +1 -0
- package/docs/ja/intlayer_with_next-intl.md +1 -0
- package/docs/ja/intlayer_with_tanstack.md +122 -3
- package/docs/ja/plugins/sync-json.md +27 -2
- package/docs/ko/dictionary/content_file.md +44 -1
- package/docs/ko/intlayer_with_astro.md +1 -1
- package/docs/ko/intlayer_with_express.md +1 -1
- package/docs/ko/intlayer_with_nestjs.md +1 -1
- package/docs/ko/intlayer_with_next-i18next.md +1 -0
- package/docs/ko/intlayer_with_next-intl.md +1 -0
- package/docs/ko/intlayer_with_tanstack.md +122 -3
- package/docs/ko/plugins/sync-json.md +27 -2
- package/docs/pl/dictionary/content_file.md +24 -1
- package/docs/pl/intlayer_with_astro.md +2 -2
- package/docs/pl/intlayer_with_express.md +1 -1
- package/docs/pl/intlayer_with_nestjs.md +1 -1
- package/docs/pl/intlayer_with_next-i18next.md +1 -0
- package/docs/pl/intlayer_with_next-intl.md +1 -0
- package/docs/pl/intlayer_with_tanstack.md +122 -3
- package/docs/pl/plugins/sync-json.md +24 -2
- package/docs/pt/dictionary/content_file.md +24 -1
- package/docs/pt/intlayer_with_astro.md +1 -1
- package/docs/pt/intlayer_with_express.md +1 -1
- package/docs/pt/intlayer_with_nestjs.md +1 -1
- package/docs/pt/intlayer_with_next-i18next.md +1 -0
- package/docs/pt/intlayer_with_next-intl.md +1 -0
- package/docs/pt/intlayer_with_tanstack.md +122 -3
- package/docs/pt/plugins/sync-json.md +27 -2
- package/docs/ru/dictionary/content_file.md +44 -1
- package/docs/ru/intlayer_with_astro.md +1 -1
- package/docs/ru/intlayer_with_express.md +1 -1
- package/docs/ru/intlayer_with_nestjs.md +1 -1
- package/docs/ru/intlayer_with_next-i18next.md +1 -0
- package/docs/ru/intlayer_with_next-intl.md +1 -0
- package/docs/ru/intlayer_with_tanstack.md +122 -3
- package/docs/ru/plugins/sync-json.md +27 -2
- package/docs/tr/dictionary/content_file.md +44 -1
- package/docs/tr/intlayer_with_astro.md +1 -1
- package/docs/tr/intlayer_with_express.md +1 -1
- package/docs/tr/intlayer_with_next-i18next.md +1 -0
- package/docs/tr/intlayer_with_next-intl.md +1 -0
- package/docs/tr/intlayer_with_tanstack.md +122 -3
- package/docs/tr/plugins/sync-json.md +27 -2
- package/docs/vi/dictionary/content_file.md +24 -1
- package/docs/vi/intlayer_with_astro.md +1 -1
- package/docs/vi/intlayer_with_express.md +1 -1
- package/docs/vi/intlayer_with_nestjs.md +1 -1
- package/docs/vi/intlayer_with_next-i18next.md +1 -0
- package/docs/vi/intlayer_with_next-intl.md +1 -0
- package/docs/vi/intlayer_with_tanstack.md +122 -3
- package/docs/vi/plugins/sync-json.md +27 -2
- package/docs/zh/dictionary/content_file.md +44 -1
- package/docs/zh/intlayer_with_astro.md +1 -1
- package/docs/zh/intlayer_with_express.md +1 -1
- package/docs/zh/intlayer_with_nestjs.md +1 -1
- package/docs/zh/intlayer_with_next-i18next.md +1 -0
- package/docs/zh/intlayer_with_next-intl.md +1 -0
- package/docs/zh/intlayer_with_tanstack.md +122 -3
- package/docs/zh/plugins/sync-json.md +27 -2
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-11
|
|
4
4
|
title: Tanstack Start 앱 번역하는 방법 – i18n 가이드 2025
|
|
5
5
|
description: Intlayer를 사용하여 Tanstack Start 애플리케이션에 국제화(i18n)를 추가하는 방법을 배우세요. 로케일 인식 라우팅으로 앱을 다국어 지원으로 만드는 종합 가이드를 따르세요.
|
|
6
6
|
keywords:
|
|
@@ -19,9 +19,12 @@ slugs:
|
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
21
|
history:
|
|
22
|
+
- version: 7.4.0
|
|
23
|
+
date: 2025-12-11
|
|
24
|
+
changes: validatePrefix 도입 및 14단계 추가: 현지화된 라우트로 404 페이지 처리.
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
|
-
changes:
|
|
27
|
+
changes: 13단계 추가: 서버 액션에서 locale 가져오기 (선택 사항)
|
|
25
28
|
- version: 5.8.1
|
|
26
29
|
date: 2025-09-09
|
|
27
30
|
changes: Tanstack Start용 추가
|
|
@@ -599,7 +602,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
599
602
|
|
|
600
603
|
---
|
|
601
604
|
|
|
602
|
-
### 14단계:
|
|
605
|
+
### 14단계: 찾을 수 없는 페이지 관리 (선택 사항)
|
|
606
|
+
|
|
607
|
+
사용자가 존재하지 않는 페이지를 방문할 때 사용자 정의 찾을 수 없음 페이지를 표시할 수 있으며, 로케일 접두사는 찾을 수 없음 페이지가 트리거되는 방식에 영향을 줄 수 있습니다.
|
|
608
|
+
|
|
609
|
+
#### 로케일 접두사로 TanStack Router의 404 처리 이해하기
|
|
610
|
+
|
|
611
|
+
TanStack Router에서 현지화된 경로로 404 페이지를 처리하려면 다층 접근 방식이 필요합니다:
|
|
612
|
+
|
|
613
|
+
1. **전용 404 경로**: 404 UI를 표시하는 특정 경로
|
|
614
|
+
2. **경로 수준 검증**: 로케일 접두사를 검증하고 잘못된 접두사를 404로 리디렉션
|
|
615
|
+
3. **Catch-all 경로**: 로케일 세그먼트 내에서 일치하지 않는 모든 경로를 캡처
|
|
616
|
+
|
|
617
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
618
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
619
|
+
|
|
620
|
+
// 이것은 전용 /[locale]/404 경로를 생성합니다
|
|
621
|
+
// 직접 경로로 사용되거나 다른 파일에서 컴포넌트로 가져올 수 있습니다
|
|
622
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
623
|
+
component: NotFoundComponent,
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
// notFoundComponent 및 catch-all 경로에서 재사용할 수 있도록 별도로 내보냅니다
|
|
627
|
+
export function NotFoundComponent() {
|
|
628
|
+
return (
|
|
629
|
+
<div>
|
|
630
|
+
<h1>404</h1>
|
|
631
|
+
</div>
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
637
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
638
|
+
import { validatePrefix } from "intlayer";
|
|
639
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
640
|
+
|
|
641
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
642
|
+
import { NotFoundComponent } from "./404";
|
|
643
|
+
|
|
644
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
645
|
+
// beforeLoad는 경로가 렌더링되기 전에 실행됩니다 (서버와 클라이언트 모두에서)
|
|
646
|
+
// 로케일 접두사를 검증하기에 이상적인 장소입니다
|
|
647
|
+
beforeLoad: ({ params }) => {
|
|
648
|
+
// 경로 매개변수에서 로케일 가져오기 (서버 헤더에서 가져오지 않음, beforeLoad는 클라이언트와 서버 모두에서 실행되기 때문)
|
|
649
|
+
const localeParam = params.locale;
|
|
650
|
+
|
|
651
|
+
// validatePrefix는 로케일이 intlayer 구성에 따라 유효한지 확인합니다
|
|
652
|
+
// 반환: { isValid: boolean, localePrefix: string }
|
|
653
|
+
// - isValid: 접두사가 구성된 로케일과 일치하면 true (또는 접두사가 선택 사항일 때 비어 있음)
|
|
654
|
+
// - localePrefix: 검증된 접두사 또는 리디렉션을 위한 기본 로케일 접두사
|
|
655
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
656
|
+
|
|
657
|
+
if (isValid) {
|
|
658
|
+
// 로케일이 유효합니다. 경로가 정상적으로 렌더링되도록 허용합니다
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// 잘못된 로케일 접두사 (예: "xyz"가 유효한 로케일이 아닌 /xyz/about)
|
|
663
|
+
// 유효한 로케일 접두사가 있는 404 페이지로 리디렉션
|
|
664
|
+
// 이것은 404 페이지가 여전히 제대로 현지화되도록 보장합니다
|
|
665
|
+
throw redirect({
|
|
666
|
+
to: "/{-$locale}/404",
|
|
667
|
+
params: { locale: localePrefix },
|
|
668
|
+
});
|
|
669
|
+
},
|
|
670
|
+
component: RouteComponent,
|
|
671
|
+
// notFoundComponent는 자식 경로가 존재하지 않을 때 호출됩니다
|
|
672
|
+
// 예: /en/존재하지-않는-페이지가 /en 레이아웃 내에서 이를 트리거합니다
|
|
673
|
+
notFoundComponent: NotFoundLayout,
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
function RouteComponent() {
|
|
677
|
+
const { defaultLocale } = useLocale();
|
|
678
|
+
const { locale } = Route.useParams();
|
|
679
|
+
|
|
680
|
+
return (
|
|
681
|
+
// 전체 로케일 세그먼트를 IntlayerProvider로 래핑
|
|
682
|
+
// 로케일 매개변수가 undefined일 때 defaultLocale로 폴백 (선택적 접두사 모드)
|
|
683
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
684
|
+
<Outlet />
|
|
685
|
+
</IntlayerProvider>
|
|
686
|
+
);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// NotFoundLayout는 404 컴포넌트를 IntlayerProvider로 래핑합니다
|
|
690
|
+
// 이것은 404 페이지에서 번역이 여전히 작동하도록 보장합니다
|
|
691
|
+
function NotFoundLayout() {
|
|
692
|
+
const { defaultLocale } = useLocale();
|
|
693
|
+
const { locale } = Route.useParams();
|
|
694
|
+
|
|
695
|
+
return (
|
|
696
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
697
|
+
<NotFoundComponent />
|
|
698
|
+
{/* 사용자가 404에서도 언어를 변경할 수 있도록 LocaleSwitcher 포함 */}
|
|
699
|
+
<LocaleSwitcher />
|
|
700
|
+
</IntlayerProvider>
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
706
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
707
|
+
|
|
708
|
+
import { NotFoundComponent } from "./404";
|
|
709
|
+
|
|
710
|
+
// $ (splat/catch-all) 경로는 다른 경로와 일치하지 않는 모든 경로와 일치합니다
|
|
711
|
+
// 예: /en/어떤/깊게/중첩된/유효하지-않은/경로
|
|
712
|
+
// 이것은 로케일 내의 일치하지 않는 모든 경로가 404 페이지를 표시하도록 보장합니다
|
|
713
|
+
// 이것이 없으면 일치하지 않는 깊은 경로가 빈 페이지나 오류를 표시할 수 있습니다
|
|
714
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
715
|
+
component: NotFoundComponent,
|
|
716
|
+
});
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
### 15단계: TypeScript 구성 (선택 사항)
|
|
603
722
|
|
|
604
723
|
Intlayer는 모듈 확장을 사용하여 TypeScript의 이점을 활용하고 코드베이스를 더욱 견고하게 만듭니다.
|
|
605
724
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Sync JSON 플러그인
|
|
5
5
|
description: Intlayer 사전을 서드파티 i18n JSON 파일(i18next, next-intl, react-intl, vue-i18n 등)과 동기화합니다. 기존 i18n을 유지하면서 Intlayer를 사용하여 메시지를 관리, 번역 및 테스트할 수 있습니다.
|
|
6
6
|
keywords:
|
|
@@ -24,12 +24,15 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 7.5.0
|
|
28
|
+
date: 2025-12-13
|
|
29
|
+
changes: ICU 및 i18next 형식 지원 추가
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: Sync JSON 플러그인 초기 문서화
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
# Sync JSON (i18n 브리지)
|
|
35
|
+
# Sync JSON (i18n 브리지) - ICU / i18next 지원이 포함된 Sync JSON
|
|
33
36
|
|
|
34
37
|
<iframe title="Intlayer와 JSON 번역을 동기화 상태로 유지하는 방법" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
38
|
|
|
@@ -105,9 +108,27 @@ syncJSON({
|
|
|
105
108
|
source: ({ key, locale }) => string, // 필수
|
|
106
109
|
location?: string, // 선택적 레이블, 기본값: "plugin"
|
|
107
110
|
priority?: number, // 충돌 해결을 위한 선택적 우선순위, 기본값: 0
|
|
111
|
+
format?: 'intlayer' | 'icu' | 'i18next', // 선택적 포맷터, 기본값: 'intlayer'
|
|
108
112
|
});
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
116
|
+
|
|
117
|
+
JSON 파일을 동기화할 때 사전 콘텐츠에 사용할 포맷터를 지정합니다. 이를 통해 다양한 i18n 라이브러리와 호환되는 다양한 메시지 포맷팅 구문을 사용할 수 있습니다.
|
|
118
|
+
|
|
119
|
+
- `'intlayer'`: 기본 Intlayer 포맷터 (기본값).
|
|
120
|
+
- `'icu'`: ICU 메시지 포맷팅을 사용합니다 (react-intl, vue-i18n과 같은 라이브러리와 호환).
|
|
121
|
+
- `'i18next'`: i18next 메시지 포맷팅을 사용합니다 (i18next, next-i18next, Solid-i18next와 호환).
|
|
122
|
+
|
|
123
|
+
**예시:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
syncJSON({
|
|
127
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
128
|
+
format: "i18next", // 호환성을 위해 i18next 포맷팅 사용
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
111
132
|
## 여러 JSON 소스 및 우선순위
|
|
112
133
|
|
|
113
134
|
여러 `syncJSON` 플러그인을 추가하여 서로 다른 JSON 소스를 동기화할 수 있습니다. 이는 프로젝트에 여러 i18n 라이브러리나 다양한 JSON 구조가 있을 때 유용합니다.
|
|
@@ -134,6 +155,7 @@ export default defineConfig({
|
|
|
134
155
|
plugins: [
|
|
135
156
|
// 주요 JSON 소스 (가장 높은 우선순위)
|
|
136
157
|
syncJSON({
|
|
158
|
+
format: "i18next",
|
|
137
159
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
138
160
|
location: "main-translations",
|
|
139
161
|
priority: 10,
|
|
@@ -141,6 +163,7 @@ export default defineConfig({
|
|
|
141
163
|
|
|
142
164
|
// 대체 JSON 소스 (낮은 우선순위)
|
|
143
165
|
syncJSON({
|
|
166
|
+
format: "i18next",
|
|
144
167
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
145
168
|
location: "fallback-translations",
|
|
146
169
|
priority: 5,
|
|
@@ -148,6 +171,7 @@ export default defineConfig({
|
|
|
148
171
|
|
|
149
172
|
// 레거시 JSON 소스 (가장 낮은 우선순위)
|
|
150
173
|
syncJSON({
|
|
174
|
+
format: "i18next",
|
|
151
175
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
152
176
|
location: "legacy-translations",
|
|
153
177
|
priority: 1,
|
|
@@ -178,6 +202,7 @@ import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
|
178
202
|
export default {
|
|
179
203
|
plugins: [
|
|
180
204
|
syncJSON({
|
|
205
|
+
format: "i18next",
|
|
181
206
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
182
207
|
}),
|
|
183
208
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Plik z Treścią
|
|
5
5
|
description: Dowiedz się, jak dostosować rozszerzenia dla plików deklaracji treści. Postępuj zgodnie z tą dokumentacją, aby efektywnie wdrażać warunki w swoim projekcie.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: Dodano obsługę formatów ICU i i18next
|
|
15
18
|
- version: 7.0.0
|
|
16
19
|
date: 2025-10-23
|
|
17
20
|
changes: Zmiana nazwy `autoFill` na `fill`
|
|
@@ -387,6 +390,26 @@ Tablica łańcuchów znaków służąca do kategoryzacji i organizacji słownik
|
|
|
387
390
|
}
|
|
388
391
|
```
|
|
389
392
|
|
|
393
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
394
|
+
|
|
395
|
+
Określa formatter do użycia dla zawartości słownika. Pozwala to na używanie różnych składni formatowania wiadomości.
|
|
396
|
+
|
|
397
|
+
- `'intlayer'`: Domyślny formatter Intlayer.
|
|
398
|
+
- `'icu'`: Używa formatowania wiadomości ICU.
|
|
399
|
+
- `'i18next'`: Używa formatowania wiadomości i18next.
|
|
400
|
+
|
|
401
|
+
**Przykład:**
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
{
|
|
405
|
+
key: "my-dictionary",
|
|
406
|
+
format: "icu",
|
|
407
|
+
content: {
|
|
408
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
390
413
|
#### `locale` (LocalesValues)
|
|
391
414
|
|
|
392
415
|
Przekształca słownik w słownik per-lokalizacyjny, gdzie każde pole zadeklarowane w zawartości zostanie automatycznie przekształcone w węzeł tłumaczenia. Gdy ta właściwość jest ustawiona:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
3
|
updatedAt: 2025-10-03
|
|
4
4
|
title: Jak przetłumaczyć swoją aplikację Astro – przewodnik i18n 2025
|
|
5
|
-
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej
|
|
5
|
+
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej strony Astro za pomocą Intlayer. Postępuj zgodnie z tym przewodnikiem, aby uczynić swoją stronę wielojęzyczną.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacjonalizacja
|
|
8
8
|
- Dokumentacja
|
|
@@ -28,7 +28,7 @@ Aby pójść dalej, możesz zaimplementować [edytor wizualny](https://github.co
|
|
|
28
28
|
createdAt: 2024-03-07
|
|
29
29
|
updatedAt: 2025-10-03
|
|
30
30
|
title: Jak przetłumaczyć swoją aplikację Astro – przewodnik i18n 2025
|
|
31
|
-
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej
|
|
31
|
+
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej strony Astro za pomocą Intlayer. Postępuj zgodnie z tym przewodnikiem, aby uczynić swoją stronę wielojęzyczną.
|
|
32
32
|
keywords:
|
|
33
33
|
|
|
34
34
|
- Internacjonalizacja
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
3
|
updatedAt: 2025-08-23
|
|
4
4
|
title: Jak przetłumaczyć backend Express – przewodnik i18n 2025
|
|
5
|
-
description: Dowiedz się, jak uczynić swój backend
|
|
5
|
+
description: Dowiedz się, jak uczynić swój backend Express wielojęzycznym. Postępuj zgodnie z dokumentacją, aby internacjonalizować (i18n) i tłumaczyć.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacjonalizacja
|
|
8
8
|
- Dokumentacja
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
3
|
updatedAt: 2025-09-09
|
|
4
4
|
title: Jak przetłumaczyć backend Nest – przewodnik i18n 2025
|
|
5
|
-
description: Dowiedz się, jak uczynić swój backend
|
|
5
|
+
description: Dowiedz się, jak uczynić swój backend NestJS wielojęzycznym. Postępuj zgodnie z dokumentacją, aby internacjonalizować (i18n) i tłumaczyć.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacjonalizacja
|
|
8
8
|
- Dokumentacja
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-11
|
|
4
4
|
title: Jak przetłumaczyć swoją aplikację Tanstack Start – przewodnik i18n 2025
|
|
5
5
|
description: Dowiedz się, jak dodać internacjonalizację (i18n) do swojej aplikacji Tanstack Start za pomocą Intlayer. Postępuj zgodnie z tym kompleksowym przewodnikiem, aby uczynić swoją aplikację wielojęzyczną z routingiem uwzględniającym lokalizację.
|
|
6
6
|
keywords:
|
|
@@ -19,9 +19,12 @@ slugs:
|
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
21
|
history:
|
|
22
|
+
- version: 7.4.0
|
|
23
|
+
date: 2025-12-11
|
|
24
|
+
changes: Wprowadzenie validatePrefix oraz dodanie kroku 14: Obsługa stron 404 z lokalizowanymi trasami.
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
|
-
changes:
|
|
27
|
+
changes: Dodany krok 13: Pobieranie lokalizacji w akcjach serwerowych (Opcjonalnie)
|
|
25
28
|
- version: 6.5.2
|
|
26
29
|
date: 2025-10-03
|
|
27
30
|
changes: Aktualizacja dokumentacji
|
|
@@ -590,7 +593,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
590
593
|
|
|
591
594
|
---
|
|
592
595
|
|
|
593
|
-
### Krok 14:
|
|
596
|
+
### Krok 14: Zarządzanie stronami nie znalezionymi (opcjonalnie)
|
|
597
|
+
|
|
598
|
+
Gdy użytkownik odwiedza nieistniejącą stronę, możesz wyświetlić niestandardową stronę "nie znaleziono", a prefiks locale może wpływać na sposób wyzwalania strony "nie znaleziono".
|
|
599
|
+
|
|
600
|
+
#### Zrozumienie obsługi 404 w TanStack Router z prefiksami locale
|
|
601
|
+
|
|
602
|
+
W TanStack Router obsługa stron 404 z zlokalizowanymi trasami wymaga podejścia wielowarstwowego:
|
|
603
|
+
|
|
604
|
+
1. **Dedykowana trasa 404**: Konkretna trasa do wyświetlenia interfejsu 404
|
|
605
|
+
2. **Walidacja na poziomie trasy**: Weryfikuje prefiksy locale i przekierowuje nieprawidłowe do 404
|
|
606
|
+
3. **Trasa catch-all**: Przechwytuje wszystkie niedopasowane ścieżki w segmencie locale
|
|
607
|
+
|
|
608
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
609
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
610
|
+
|
|
611
|
+
// To tworzy dedykowaną trasę /[locale]/404
|
|
612
|
+
// Jest używana zarówno jako bezpośrednia trasa, jak i importowana jako komponent w innych plikach
|
|
613
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
614
|
+
component: NotFoundComponent,
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// Eksportowane osobno, aby można było ponownie użyć w notFoundComponent i trasach catch-all
|
|
618
|
+
export function NotFoundComponent() {
|
|
619
|
+
return (
|
|
620
|
+
<div>
|
|
621
|
+
<h1>404</h1>
|
|
622
|
+
</div>
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
628
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
629
|
+
import { validatePrefix } from "intlayer";
|
|
630
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
631
|
+
|
|
632
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
633
|
+
import { NotFoundComponent } from "./404";
|
|
634
|
+
|
|
635
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
636
|
+
// beforeLoad uruchamia się przed renderowaniem trasy (zarówno na serwerze, jak i kliencie)
|
|
637
|
+
// To idealne miejsce do walidacji prefiksu locale
|
|
638
|
+
beforeLoad: ({ params }) => {
|
|
639
|
+
// Pobierz locale z parametrów trasy (nie z nagłówków serwera, ponieważ beforeLoad działa zarówno na kliencie, jak i serwerze)
|
|
640
|
+
const localeParam = params.locale;
|
|
641
|
+
|
|
642
|
+
// validatePrefix sprawdza, czy locale jest prawidłowe zgodnie z konfiguracją intlayer
|
|
643
|
+
// Zwraca: { isValid: boolean, localePrefix: string }
|
|
644
|
+
// - isValid: true, jeśli prefiks pasuje do skonfigurowanego locale (lub jest pusty, gdy prefiks jest opcjonalny)
|
|
645
|
+
// - localePrefix: zwalidowany prefiks lub domyślny prefiks locale do przekierowań
|
|
646
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
647
|
+
|
|
648
|
+
if (isValid) {
|
|
649
|
+
// Locale jest prawidłowe, pozwól trasie renderować się normalnie
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Nieprawidłowy prefiks locale (np. /xyz/about, gdzie "xyz" nie jest prawidłowym locale)
|
|
654
|
+
// Przekieruj do strony 404 z prawidłowym prefiksem locale
|
|
655
|
+
// To zapewnia, że strona 404 jest nadal prawidłowo zlokalizowana
|
|
656
|
+
throw redirect({
|
|
657
|
+
to: "/{-$locale}/404",
|
|
658
|
+
params: { locale: localePrefix },
|
|
659
|
+
});
|
|
660
|
+
},
|
|
661
|
+
component: RouteComponent,
|
|
662
|
+
// notFoundComponent jest wywoływane, gdy trasa potomna nie istnieje
|
|
663
|
+
// np. /en/nieistniejaca-strona wyzwala to w układzie /en
|
|
664
|
+
notFoundComponent: NotFoundLayout,
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
function RouteComponent() {
|
|
668
|
+
const { defaultLocale } = useLocale();
|
|
669
|
+
const { locale } = Route.useParams();
|
|
670
|
+
|
|
671
|
+
return (
|
|
672
|
+
// Owiń cały segment locale w IntlayerProvider
|
|
673
|
+
// Powraca do defaultLocale, gdy parametr locale jest undefined (tryb opcjonalnego prefiksu)
|
|
674
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
675
|
+
<Outlet />
|
|
676
|
+
</IntlayerProvider>
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// NotFoundLayout owija komponent 404 w IntlayerProvider
|
|
681
|
+
// To zapewnia, że tłumaczenia nadal działają na stronie 404
|
|
682
|
+
function NotFoundLayout() {
|
|
683
|
+
const { defaultLocale } = useLocale();
|
|
684
|
+
const { locale } = Route.useParams();
|
|
685
|
+
|
|
686
|
+
return (
|
|
687
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
688
|
+
<NotFoundComponent />
|
|
689
|
+
{/* Dołącz LocaleSwitcher, aby użytkownicy mogli zmieniać język nawet na 404 */}
|
|
690
|
+
<LocaleSwitcher />
|
|
691
|
+
</IntlayerProvider>
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
697
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
698
|
+
|
|
699
|
+
import { NotFoundComponent } from "./404";
|
|
700
|
+
|
|
701
|
+
// Trasa $ (splat/catch-all) pasuje do każdej ścieżki, która nie pasuje do innych tras
|
|
702
|
+
// np. /en/jakas/gleboko/zagniezdzona/niewazna/sciezka
|
|
703
|
+
// To zapewnia, że WSZYSTKIE niedopasowane ścieżki w locale wyświetlają stronę 404
|
|
704
|
+
// Bez tego niedopasowane głębokie ścieżki mogą wyświetlać pustą stronę lub błąd
|
|
705
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
706
|
+
component: NotFoundComponent,
|
|
707
|
+
});
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
### Krok 15: Konfiguracja TypeScript (opcjonalnie)
|
|
594
713
|
|
|
595
714
|
Intlayer używa rozszerzenia modułów (module augmentation), aby wykorzystać zalety TypeScript i wzmocnić Twoją bazę kodu.
|
|
596
715
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Wtyczka Sync JSON
|
|
5
5
|
description: Synchronizuj słowniki Intlayer z zewnętrznymi plikami JSON i18n (i18next, next-intl, react-intl, vue-i18n i inne). Zachowaj istniejące i18n, korzystając z Intlayer do zarządzania, tłumaczenia i testowania swoich komunikatów.
|
|
6
6
|
keywords:
|
|
@@ -29,7 +29,7 @@ history:
|
|
|
29
29
|
changes: Pierwsza dokumentacja wtyczki Sync JSON
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
# Sync JSON (mosty i18n)
|
|
32
|
+
# Sync JSON (mosty i18n) - Sync JSON z obsługą ICU / i18next
|
|
33
33
|
|
|
34
34
|
<iframe title="Jak zachować synchronizację tłumaczeń JSON z Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
35
|
|
|
@@ -105,9 +105,27 @@ syncJSON({
|
|
|
105
105
|
source: ({ key, locale }) => string, // wymagane
|
|
106
106
|
location?: string, // opcjonalna etykieta, domyślnie: "plugin"
|
|
107
107
|
priority?: number, // opcjonalny priorytet do rozstrzygania konfliktów, domyślnie: 0
|
|
108
|
+
format?: 'intlayer' | 'icu' | 'i18next', // opcjonalny formatator, domyślnie: 'intlayer'
|
|
108
109
|
});
|
|
109
110
|
```
|
|
110
111
|
|
|
112
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
113
|
+
|
|
114
|
+
Określa formatator, który będzie używany do zawartości słownika podczas synchronizacji plików JSON. Pozwala to na używanie różnych składni formatowania wiadomości zgodnych z różnymi bibliotekami i18n.
|
|
115
|
+
|
|
116
|
+
- `'intlayer'`: Domyślny formatator Intlayer (domyślnie).
|
|
117
|
+
- `'icu'`: Używa formatowania wiadomości ICU (zgodne z bibliotekami takimi jak react-intl, vue-i18n).
|
|
118
|
+
- `'i18next'`: Używa formatowania wiadomości i18next (zgodne z i18next, next-i18next, Solid-i18next).
|
|
119
|
+
|
|
120
|
+
**Przykład:**
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
syncJSON({
|
|
124
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
125
|
+
format: "i18next", // Użyj formatowania i18next dla zgodności
|
|
126
|
+
}),
|
|
127
|
+
```
|
|
128
|
+
|
|
111
129
|
## Wiele źródeł JSON i priorytet
|
|
112
130
|
|
|
113
131
|
Możesz dodać wiele wtyczek `syncJSON`, aby synchronizować różne źródła JSON. Jest to przydatne, gdy masz wiele bibliotek i18n lub różne struktury JSON w swoim projekcie.
|
|
@@ -134,6 +152,7 @@ export default defineConfig({
|
|
|
134
152
|
plugins: [
|
|
135
153
|
// Główne źródło JSON (najwyższy priorytet)
|
|
136
154
|
syncJSON({
|
|
155
|
+
format: "i18next",
|
|
137
156
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
138
157
|
location: "main-translations",
|
|
139
158
|
priority: 10,
|
|
@@ -141,6 +160,7 @@ export default defineConfig({
|
|
|
141
160
|
|
|
142
161
|
// Zapasowe źródło JSON (niższy priorytet)
|
|
143
162
|
syncJSON({
|
|
163
|
+
format: "i18next",
|
|
144
164
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
145
165
|
location: "fallback-translations",
|
|
146
166
|
priority: 5,
|
|
@@ -148,6 +168,7 @@ export default defineConfig({
|
|
|
148
168
|
|
|
149
169
|
// Źródło JSON dziedziczone (najniższy priorytet)
|
|
150
170
|
syncJSON({
|
|
171
|
+
format: "i18next",
|
|
151
172
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
152
173
|
location: "legacy-translations",
|
|
153
174
|
priority: 1,
|
|
@@ -178,6 +199,7 @@ import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
|
178
199
|
export default {
|
|
179
200
|
plugins: [
|
|
180
201
|
syncJSON({
|
|
202
|
+
format: "i18next",
|
|
181
203
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
182
204
|
}),
|
|
183
205
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Arquivo de Conteúdo
|
|
5
5
|
description: Aprenda como personalizar as extensões para seus arquivos de declaração de conteúdo. Siga esta documentação para implementar condições de forma eficiente em seu projeto.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: Adicionado suporte para formatos ICU e i18next
|
|
15
18
|
- version: 6.0.0
|
|
16
19
|
date: 2025-09-20
|
|
17
20
|
changes: Adição da documentação dos campos
|
|
@@ -387,6 +390,26 @@ Array de strings para categorizar e organizar dicionários. As tags fornecem con
|
|
|
387
390
|
}
|
|
388
391
|
```
|
|
389
392
|
|
|
393
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
394
|
+
|
|
395
|
+
Especifica o formatador a ser usado para o conteúdo do dicionário. Isso permite usar diferentes sintaxes de formatação de mensagens.
|
|
396
|
+
|
|
397
|
+
- `'intlayer'`: O formatador Intlayer padrão.
|
|
398
|
+
- `'icu'`: Usa formatação de mensagens ICU.
|
|
399
|
+
- `'i18next'`: Usa formatação de mensagens i18next.
|
|
400
|
+
|
|
401
|
+
**Exemplo:**
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
{
|
|
405
|
+
key: "my-dictionary",
|
|
406
|
+
format: "icu",
|
|
407
|
+
content: {
|
|
408
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
390
413
|
#### `locale` (LocalesValues)
|
|
391
414
|
|
|
392
415
|
Transforma o dicionário em um dicionário por localidade onde cada campo declarado no conteúdo será automaticamente transformado em um nó de tradução. Quando essa propriedade é definida:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
3
|
updatedAt: 2025-10-03
|
|
4
4
|
title: Como traduzir seu Astro – guia i18n 2025
|
|
5
|
-
description: Aprenda como adicionar internacionalização (i18n)
|
|
5
|
+
description: Aprenda como adicionar internacionalização (i18n) ao seu site Astro usando Intlayer. Siga este guia para tornar seu site multilíngue.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalização
|
|
8
8
|
- Documentação
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-08-11
|
|
3
3
|
updatedAt: 2025-06-29
|
|
4
4
|
title: Como traduzir seu Express backend – guia i18n 2025
|
|
5
|
-
description: Descubra como tornar seu backend
|
|
5
|
+
description: Descubra como tornar seu backend Express multilíngue. Siga a documentação para internacionalizar (i18n) e traduzi-lo.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalização
|
|
8
8
|
- Documentação
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
3
|
updatedAt: 2025-09-09
|
|
4
4
|
title: Como traduzir seu Nest backend – guia i18n 2025
|
|
5
|
-
description: Descubra como tornar seu backend
|
|
5
|
+
description: Descubra como tornar seu backend NestJS multilíngue. Siga a documentação para internacionalizar (i18n) e traduzir.
|
|
6
6
|
keywords:
|
|
7
7
|
- Internacionalização
|
|
8
8
|
- Documentação
|