@intlayer/docs 6.1.5 → 6.1.6-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/next-i18next_vs_next-intl_vs_intlayer.md +404 -173
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +262 -113
- package/blog/en/intlayer_with_next-i18next.mdx +431 -0
- package/blog/en/intlayer_with_next-intl.mdx +335 -0
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +403 -140
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +185 -71
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +36 -28
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +38 -28
- package/dist/cjs/generated/docs.entry.cjs +16 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +16 -0
- package/dist/esm/generated/docs.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/component_i18n.md +186 -0
- package/docs/ar/vs_code_extension.md +48 -109
- package/docs/de/component_i18n.md +186 -0
- package/docs/de/vs_code_extension.md +46 -107
- package/docs/en/component_i18n.md +186 -0
- package/docs/en/intlayer_with_nextjs_14.md +18 -1
- package/docs/en/intlayer_with_nextjs_15.md +18 -1
- package/docs/en/vs_code_extension.md +24 -114
- package/docs/en-GB/component_i18n.md +186 -0
- package/docs/en-GB/vs_code_extension.md +42 -103
- package/docs/es/component_i18n.md +182 -0
- package/docs/es/vs_code_extension.md +53 -114
- package/docs/fr/component_i18n.md +186 -0
- package/docs/fr/vs_code_extension.md +50 -111
- package/docs/hi/component_i18n.md +186 -0
- package/docs/hi/vs_code_extension.md +49 -110
- package/docs/it/component_i18n.md +186 -0
- package/docs/it/vs_code_extension.md +50 -111
- package/docs/ja/component_i18n.md +186 -0
- package/docs/ja/vs_code_extension.md +50 -111
- package/docs/ko/component_i18n.md +186 -0
- package/docs/ko/vs_code_extension.md +48 -109
- package/docs/pt/component_i18n.md +186 -0
- package/docs/pt/vs_code_extension.md +46 -107
- package/docs/ru/component_i18n.md +186 -0
- package/docs/ru/vs_code_extension.md +48 -109
- package/docs/tr/component_i18n.md +186 -0
- package/docs/tr/vs_code_extension.md +54 -115
- package/docs/zh/component_i18n.md +186 -0
- package/docs/zh/vs_code_extension.md +51 -105
- package/package.json +11 -11
- package/src/generated/docs.entry.ts +16 -0
|
@@ -19,6 +19,8 @@ slugs:
|
|
|
19
19
|
|
|
20
20
|
# next-i18next VS next-intl VS intlayer | Internazionalizzazione (i18n) in Next.js
|
|
21
21
|
|
|
22
|
+

|
|
23
|
+
|
|
22
24
|
Diamo un'occhiata alle somiglianze e differenze tra tre opzioni i18n per Next.js: next-i18next, next-intl e Intlayer.
|
|
23
25
|
|
|
24
26
|
Questo non è un tutorial completo. È un confronto per aiutarti a scegliere.
|
|
@@ -173,9 +175,9 @@ Nel caso di `next-intl` e `next-i18next`, la libreria richiede il caricamento de
|
|
|
173
175
|
|
|
174
176
|
Ecco un esempio dell'impatto dell'ottimizzazione della dimensione del bundle utilizzando `intlayer` in un'applicazione vite + react:
|
|
175
177
|
|
|
176
|
-
| Bundle ottimizzato
|
|
177
|
-
|
|
|
178
|
-
|  |  |
|
|
178
|
+
| Bundle ottimizzato | Bundle non ottimizzato |
|
|
179
|
+
| ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
180
|
+
|  |  |
|
|
179
181
|
|
|
180
182
|
---
|
|
181
183
|
|
|
@@ -348,25 +350,25 @@ La struttura dell'app è importante per garantire una buona manutenibilità del
|
|
|
348
350
|
|
|
349
351
|
```bash
|
|
350
352
|
.
|
|
351
|
-
├──
|
|
352
|
-
│ └── locales
|
|
353
|
-
│ ├── en
|
|
354
|
-
│ │ ├── home.json
|
|
355
|
-
│ │ └── navbar.json
|
|
356
|
-
│ ├── fr
|
|
357
|
-
│ │ ├── home.json
|
|
358
|
-
│ │ └── navbar.json
|
|
359
|
-
│ └── es
|
|
360
|
-
│ ├── home.json
|
|
361
|
-
│ └── navbar.json
|
|
362
|
-
├── next-i18next.config.js
|
|
353
|
+
├── i18n.config.ts
|
|
363
354
|
└── src
|
|
364
|
-
├──
|
|
355
|
+
├── locales
|
|
356
|
+
│ ├── en
|
|
357
|
+
│ │ ├── common.json
|
|
358
|
+
│ │ └── about.json
|
|
359
|
+
│ └── fr
|
|
360
|
+
│ ├── common.json
|
|
361
|
+
│ └── about.json
|
|
365
362
|
├── app
|
|
366
|
-
│
|
|
363
|
+
│ ├── i18n
|
|
364
|
+
│ │ └── server.ts
|
|
365
|
+
│ └── [locale]
|
|
366
|
+
│ ├── layout.tsx
|
|
367
|
+
│ └── about.tsx
|
|
367
368
|
└── components
|
|
368
|
-
|
|
369
|
-
|
|
369
|
+
├── I18nProvider.tsx
|
|
370
|
+
├── ClientComponent.tsx
|
|
371
|
+
└── ServerComponent.tsx
|
|
370
372
|
```
|
|
371
373
|
|
|
372
374
|
</TabItem>
|
|
@@ -374,6 +376,7 @@ La struttura dell'app è importante per garantire una buona manutenibilità del
|
|
|
374
376
|
|
|
375
377
|
```bash
|
|
376
378
|
.
|
|
379
|
+
├── i18n.ts
|
|
377
380
|
├── locales
|
|
378
381
|
│ ├── en
|
|
379
382
|
│ │ ├── home.json
|
|
@@ -384,11 +387,13 @@ La struttura dell'app è importante per garantire una buona manutenibilità del
|
|
|
384
387
|
│ └── es
|
|
385
388
|
│ ├── home.json
|
|
386
389
|
│ └── navbar.json
|
|
387
|
-
├── i18n.ts
|
|
388
390
|
└── src
|
|
389
391
|
├── middleware.ts
|
|
390
392
|
├── app
|
|
391
|
-
│
|
|
393
|
+
│ ├── i18n
|
|
394
|
+
│ │ └── server.ts
|
|
395
|
+
│ └── [locale]
|
|
396
|
+
│ └── home.tsx
|
|
392
397
|
└── components
|
|
393
398
|
└── Navbar
|
|
394
399
|
└── index.tsx
|
|
@@ -403,9 +408,11 @@ La struttura dell'app è importante per garantire una buona manutenibilità del
|
|
|
403
408
|
└── src
|
|
404
409
|
├── middleware.ts
|
|
405
410
|
├── app
|
|
406
|
-
│ └──
|
|
407
|
-
│
|
|
408
|
-
│ └──
|
|
411
|
+
│ └── [locale]
|
|
412
|
+
│ ├── layout.tsx
|
|
413
|
+
│ └── home
|
|
414
|
+
│ ├── index.tsx
|
|
415
|
+
│ └── index.content.ts
|
|
409
416
|
└── components
|
|
410
417
|
└── Navbar
|
|
411
418
|
├── index.tsx
|
|
@@ -533,8 +540,10 @@ export default async function LocaleLayout({
|
|
|
533
540
|
const messages = await getMessages();
|
|
534
541
|
const clientMessages = pick(messages, ["common", "about"]);
|
|
535
542
|
|
|
543
|
+
const rtlLocales = ["ar", "he", "fa", "ur"];
|
|
544
|
+
|
|
536
545
|
return (
|
|
537
|
-
<html lang={locale}>
|
|
546
|
+
<html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>
|
|
538
547
|
<body>
|
|
539
548
|
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
540
549
|
{children}
|
|
@@ -851,10 +860,11 @@ const ServerComponent = ({ count }: ServerComponentProps) => {
|
|
|
851
860
|
type ServerComponentProps = {
|
|
852
861
|
count: number;
|
|
853
862
|
t: (key: string) => string;
|
|
863
|
+
formatter: Intl.NumberFormat;
|
|
854
864
|
};
|
|
855
865
|
|
|
856
|
-
const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
857
|
-
const formatted =
|
|
866
|
+
const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {
|
|
867
|
+
const formatted = formatter.format(count);
|
|
858
868
|
|
|
859
869
|
return (
|
|
860
870
|
<div>
|
|
@@ -868,7 +878,7 @@ const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
|
868
878
|
> Poiché il componente server non può essere asincrono, è necessario passare le traduzioni e la funzione di formattazione come props.
|
|
869
879
|
>
|
|
870
880
|
> - `const t = await getTranslations("about.counter");`
|
|
871
|
-
> - `const
|
|
881
|
+
> - `const formatter = await getFormatter().then((formatter) => formatter.number());`
|
|
872
882
|
|
|
873
883
|
</TabItem>
|
|
874
884
|
<TabItem label="intlayer" value="intlayer">
|
|
@@ -19,6 +19,8 @@ slugs:
|
|
|
19
19
|
|
|
20
20
|
# next-i18next VS next-intl VS intlayer | Next.jsの国際化(i18n)
|
|
21
21
|
|
|
22
|
+

|
|
23
|
+
|
|
22
24
|
Next.js向けの3つのi18nオプション、next-i18next、next-intl、Intlayerの類似点と相違点を見ていきましょう。
|
|
23
25
|
|
|
24
26
|
これは完全なチュートリアルではなく、選択の参考となる比較です。
|
|
@@ -173,9 +175,9 @@ Next.jsは国際化されたルーティング(例:ロケールセグメン
|
|
|
173
175
|
|
|
174
176
|
以下は、vite + react アプリケーションで `intlayer` を使用したバンドルサイズ最適化の影響の例です:
|
|
175
177
|
|
|
176
|
-
| 最適化されたバンドル
|
|
177
|
-
|
|
|
178
|
-
|  |  |
|
|
178
|
+
| 最適化されたバンドル | 最適化されていないバンドル |
|
|
179
|
+
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
180
|
+
|  |  |
|
|
179
181
|
|
|
180
182
|
---
|
|
181
183
|
|
|
@@ -348,25 +350,25 @@ Next.jsは国際化されたルーティング(例:ロケールセグメン
|
|
|
348
350
|
|
|
349
351
|
```bash
|
|
350
352
|
.
|
|
351
|
-
├──
|
|
352
|
-
│ └── locales
|
|
353
|
-
│ ├── en
|
|
354
|
-
│ │ ├── home.json
|
|
355
|
-
│ │ └── navbar.json
|
|
356
|
-
│ ├── fr
|
|
357
|
-
│ │ ├── home.json
|
|
358
|
-
│ │ └── navbar.json
|
|
359
|
-
│ └── es
|
|
360
|
-
│ ├── home.json
|
|
361
|
-
│ └── navbar.json
|
|
362
|
-
├── next-i18next.config.js
|
|
353
|
+
├── i18n.config.ts
|
|
363
354
|
└── src
|
|
364
|
-
├──
|
|
355
|
+
├── locales
|
|
356
|
+
│ ├── en
|
|
357
|
+
│ │ ├── common.json
|
|
358
|
+
│ │ └── about.json
|
|
359
|
+
│ └── fr
|
|
360
|
+
│ ├── common.json
|
|
361
|
+
│ └── about.json
|
|
365
362
|
├── app
|
|
366
|
-
│
|
|
363
|
+
│ ├── i18n
|
|
364
|
+
│ │ └── server.ts
|
|
365
|
+
│ └── [locale]
|
|
366
|
+
│ ├── layout.tsx
|
|
367
|
+
│ └── about.tsx
|
|
367
368
|
└── components
|
|
368
|
-
|
|
369
|
-
|
|
369
|
+
├── I18nProvider.tsx
|
|
370
|
+
├── ClientComponent.tsx
|
|
371
|
+
└── ServerComponent.tsx
|
|
370
372
|
```
|
|
371
373
|
|
|
372
374
|
</TabItem>
|
|
@@ -374,6 +376,7 @@ Next.jsは国際化されたルーティング(例:ロケールセグメン
|
|
|
374
376
|
|
|
375
377
|
```bash
|
|
376
378
|
.
|
|
379
|
+
├── i18n.ts
|
|
377
380
|
├── locales
|
|
378
381
|
│ ├── en
|
|
379
382
|
│ │ ├── home.json
|
|
@@ -384,11 +387,13 @@ Next.jsは国際化されたルーティング(例:ロケールセグメン
|
|
|
384
387
|
│ └── es
|
|
385
388
|
│ ├── home.json
|
|
386
389
|
│ └── navbar.json
|
|
387
|
-
├── i18n.ts
|
|
388
390
|
└── src
|
|
389
391
|
├── middleware.ts
|
|
390
392
|
├── app
|
|
391
|
-
│
|
|
393
|
+
│ ├── i18n
|
|
394
|
+
│ │ └── server.ts
|
|
395
|
+
│ └── [locale]
|
|
396
|
+
│ └── home.tsx
|
|
392
397
|
└── components
|
|
393
398
|
└── Navbar
|
|
394
399
|
└── index.tsx
|
|
@@ -403,9 +408,11 @@ Next.jsは国際化されたルーティング(例:ロケールセグメン
|
|
|
403
408
|
└── src
|
|
404
409
|
├── middleware.ts
|
|
405
410
|
├── app
|
|
406
|
-
│ └──
|
|
407
|
-
│
|
|
408
|
-
│ └──
|
|
411
|
+
│ └── [locale]
|
|
412
|
+
│ ├── layout.tsx
|
|
413
|
+
│ └── home
|
|
414
|
+
│ ├── index.tsx
|
|
415
|
+
│ └── index.content.ts
|
|
409
416
|
└── components
|
|
410
417
|
└── Navbar
|
|
411
418
|
├── index.tsx
|
|
@@ -533,8 +540,10 @@ export default async function LocaleLayout({
|
|
|
533
540
|
const messages = await getMessages();
|
|
534
541
|
const clientMessages = pick(messages, ["common", "about"]);
|
|
535
542
|
|
|
543
|
+
const rtlLocales = ["ar", "he", "fa", "ur"];
|
|
544
|
+
|
|
536
545
|
return (
|
|
537
|
-
<html lang={locale}>
|
|
546
|
+
<html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>
|
|
538
547
|
<body>
|
|
539
548
|
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
540
549
|
{children}
|
|
@@ -851,10 +860,11 @@ const ServerComponent = ({ count }: ServerComponentProps) => {
|
|
|
851
860
|
type ServerComponentProps = {
|
|
852
861
|
count: number;
|
|
853
862
|
t: (key: string) => string;
|
|
863
|
+
formatter: Intl.NumberFormat;
|
|
854
864
|
};
|
|
855
865
|
|
|
856
|
-
const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
857
|
-
const formatted =
|
|
866
|
+
const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {
|
|
867
|
+
const formatted = formatter.format(count);
|
|
858
868
|
|
|
859
869
|
return (
|
|
860
870
|
<div>
|
|
@@ -868,7 +878,7 @@ const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
|
868
878
|
> サーバーコンポーネントは非同期にできないため、翻訳関数とフォーマッター関数をプロパティとして渡す必要があります。
|
|
869
879
|
>
|
|
870
880
|
> - `const t = await getTranslations("about.counter");`
|
|
871
|
-
> - `const
|
|
881
|
+
> - `const formatter = await getFormatter().then((formatter) => formatter.number());`
|
|
872
882
|
|
|
873
883
|
</TabItem>
|
|
874
884
|
<TabItem label="intlayer" value="intlayer">
|
|
@@ -19,6 +19,8 @@ slugs:
|
|
|
19
19
|
|
|
20
20
|
# next-i18next VS next-intl VS intlayer | Next.js 국제화 (i18n)
|
|
21
21
|
|
|
22
|
+

|
|
23
|
+
|
|
22
24
|
Next.js를 위한 세 가지 i18n 옵션인 next-i18next, next-intl, Intlayer의 유사점과 차이점을 살펴보겠습니다.
|
|
23
25
|
|
|
24
26
|
이 문서는 완전한 튜토리얼이 아니라 선택에 도움을 주기 위한 비교입니다.
|
|
@@ -165,9 +167,9 @@ Next.js는 국제화된 라우팅(예: 로케일 세그먼트)을 기본적으
|
|
|
165
167
|
|
|
166
168
|
다음은 vite + react 애플리케이션에서 `intlayer`를 사용한 번들 크기 최적화의 영향 예시입니다:
|
|
167
169
|
|
|
168
|
-
| 최적화된 번들
|
|
169
|
-
|
|
|
170
|
-
|  |  |
|
|
170
|
+
| 최적화된 번들 | 최적화되지 않은 번들 |
|
|
171
|
+
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
172
|
+
|  |  |
|
|
171
173
|
|
|
172
174
|
---
|
|
173
175
|
|
|
@@ -340,25 +342,25 @@ Next.js는 국제화된 라우팅(예: 로케일 세그먼트)을 기본적으
|
|
|
340
342
|
|
|
341
343
|
```bash
|
|
342
344
|
.
|
|
343
|
-
├──
|
|
344
|
-
│ └── locales
|
|
345
|
-
│ ├── en
|
|
346
|
-
│ │ ├── home.json
|
|
347
|
-
│ │ └── navbar.json
|
|
348
|
-
│ ├── fr
|
|
349
|
-
│ │ ├── home.json
|
|
350
|
-
│ │ └── navbar.json
|
|
351
|
-
│ └── es
|
|
352
|
-
│ ├── home.json
|
|
353
|
-
│ └── navbar.json
|
|
354
|
-
├── next-i18next.config.js
|
|
345
|
+
├── i18n.config.ts
|
|
355
346
|
└── src
|
|
356
|
-
├──
|
|
347
|
+
├── locales
|
|
348
|
+
│ ├── en
|
|
349
|
+
│ │ ├── common.json
|
|
350
|
+
│ │ └── about.json
|
|
351
|
+
│ └── fr
|
|
352
|
+
│ ├── common.json
|
|
353
|
+
│ └── about.json
|
|
357
354
|
├── app
|
|
358
|
-
│
|
|
355
|
+
│ ├── i18n
|
|
356
|
+
│ │ └── server.ts
|
|
357
|
+
│ └── [locale]
|
|
358
|
+
│ ├── layout.tsx
|
|
359
|
+
│ └── about.tsx
|
|
359
360
|
└── components
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
├── I18nProvider.tsx
|
|
362
|
+
├── ClientComponent.tsx
|
|
363
|
+
└── ServerComponent.tsx
|
|
362
364
|
```
|
|
363
365
|
|
|
364
366
|
</TabItem>
|
|
@@ -366,6 +368,7 @@ Next.js는 국제화된 라우팅(예: 로케일 세그먼트)을 기본적으
|
|
|
366
368
|
|
|
367
369
|
```bash
|
|
368
370
|
.
|
|
371
|
+
├── i18n.ts
|
|
369
372
|
├── locales
|
|
370
373
|
│ ├── en
|
|
371
374
|
│ │ ├── home.json
|
|
@@ -376,11 +379,13 @@ Next.js는 국제화된 라우팅(예: 로케일 세그먼트)을 기본적으
|
|
|
376
379
|
│ └── es
|
|
377
380
|
│ ├── home.json
|
|
378
381
|
│ └── navbar.json
|
|
379
|
-
├── i18n.ts
|
|
380
382
|
└── src
|
|
381
383
|
├── middleware.ts
|
|
382
384
|
├── app
|
|
383
|
-
│
|
|
385
|
+
│ ├── i18n
|
|
386
|
+
│ │ └── server.ts
|
|
387
|
+
│ └── [locale]
|
|
388
|
+
│ └── home.tsx
|
|
384
389
|
└── components
|
|
385
390
|
└── Navbar
|
|
386
391
|
└── index.tsx
|
|
@@ -395,9 +400,11 @@ Next.js는 국제화된 라우팅(예: 로케일 세그먼트)을 기본적으
|
|
|
395
400
|
└── src
|
|
396
401
|
├── middleware.ts
|
|
397
402
|
├── app
|
|
398
|
-
│ └──
|
|
399
|
-
│
|
|
400
|
-
│ └──
|
|
403
|
+
│ └── [locale]
|
|
404
|
+
│ ├── layout.tsx
|
|
405
|
+
│ └── home
|
|
406
|
+
│ ├── index.tsx
|
|
407
|
+
│ └── index.content.ts
|
|
401
408
|
└── components
|
|
402
409
|
└── Navbar
|
|
403
410
|
├── index.tsx
|
|
@@ -525,8 +532,10 @@ export default async function LocaleLayout({
|
|
|
525
532
|
const messages = await getMessages();
|
|
526
533
|
const clientMessages = pick(messages, ["common", "about"]);
|
|
527
534
|
|
|
535
|
+
const rtlLocales = ["ar", "he", "fa", "ur"];
|
|
536
|
+
|
|
528
537
|
return (
|
|
529
|
-
<html lang={locale}>
|
|
538
|
+
<html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>
|
|
530
539
|
<body>
|
|
531
540
|
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
532
541
|
{children}
|
|
@@ -843,10 +852,11 @@ const ServerComponent = ({ count }: ServerComponentProps) => {
|
|
|
843
852
|
type ServerComponentProps = {
|
|
844
853
|
count: number;
|
|
845
854
|
t: (key: string) => string;
|
|
855
|
+
formatter: Intl.NumberFormat;
|
|
846
856
|
};
|
|
847
857
|
|
|
848
|
-
const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
849
|
-
const formatted =
|
|
858
|
+
const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {
|
|
859
|
+
const formatted = formatter.format(count);
|
|
850
860
|
|
|
851
861
|
return (
|
|
852
862
|
<div>
|
|
@@ -860,7 +870,7 @@ const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
|
860
870
|
> 서버 컴포넌트는 비동기(async)일 수 없으므로, 번역 함수와 포맷터 함수를 props로 전달해야 합니다.
|
|
861
871
|
>
|
|
862
872
|
> - `const t = await getTranslations("about.counter");`
|
|
863
|
-
> - `const
|
|
873
|
+
> - `const formatter = await getFormatter().then((formatter) => formatter.number());`
|
|
864
874
|
|
|
865
875
|
</TabItem>
|
|
866
876
|
<TabItem label="intlayer" value="intlayer">
|
|
@@ -19,6 +19,8 @@ slugs:
|
|
|
19
19
|
|
|
20
20
|
# next-i18next VS next-intl VS intlayer | Internacionalização (i18n) no Next.js
|
|
21
21
|
|
|
22
|
+

|
|
23
|
+
|
|
22
24
|
Vamos analisar as semelhanças e diferenças entre três opções de i18n para Next.js: next-i18next, next-intl e Intlayer.
|
|
23
25
|
|
|
24
26
|
Este não é um tutorial completo. É uma comparação para ajudar você a escolher.
|
|
@@ -165,9 +167,9 @@ No caso do `next-intl` e do `next-i18next`, a biblioteca exige o carregamento do
|
|
|
165
167
|
|
|
166
168
|
Aqui está um exemplo do impacto da otimização do tamanho do bundle usando `intlayer` em uma aplicação vite + react:
|
|
167
169
|
|
|
168
|
-
| Bundle otimizado
|
|
169
|
-
|
|
|
170
|
-
|  |  |
|
|
170
|
+
| Bundle otimizado | Bundle não otimizado |
|
|
171
|
+
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
172
|
+
|  |  |
|
|
171
173
|
|
|
172
174
|
---
|
|
173
175
|
|
|
@@ -340,25 +342,25 @@ A estrutura do aplicativo é importante para garantir uma boa manutenção da su
|
|
|
340
342
|
|
|
341
343
|
```bash
|
|
342
344
|
.
|
|
343
|
-
├──
|
|
344
|
-
│ └── locales
|
|
345
|
-
│ ├── en
|
|
346
|
-
│ │ ├── home.json
|
|
347
|
-
│ │ └── navbar.json
|
|
348
|
-
│ ├── fr
|
|
349
|
-
│ │ ├── home.json
|
|
350
|
-
│ │ └── navbar.json
|
|
351
|
-
│ └── es
|
|
352
|
-
│ ├── home.json
|
|
353
|
-
│ └── navbar.json
|
|
354
|
-
├── next-i18next.config.js
|
|
345
|
+
├── i18n.config.ts
|
|
355
346
|
└── src
|
|
356
|
-
├──
|
|
347
|
+
├── locales
|
|
348
|
+
│ ├── en
|
|
349
|
+
│ │ ├── common.json
|
|
350
|
+
│ │ └── about.json
|
|
351
|
+
│ └── fr
|
|
352
|
+
│ ├── common.json
|
|
353
|
+
│ └── about.json
|
|
357
354
|
├── app
|
|
358
|
-
│
|
|
355
|
+
│ ├── i18n
|
|
356
|
+
│ │ └── server.ts
|
|
357
|
+
│ └── [locale]
|
|
358
|
+
│ ├── layout.tsx
|
|
359
|
+
│ └── about.tsx
|
|
359
360
|
└── components
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
├── I18nProvider.tsx
|
|
362
|
+
├── ClientComponent.tsx
|
|
363
|
+
└── ServerComponent.tsx
|
|
362
364
|
```
|
|
363
365
|
|
|
364
366
|
</TabItem>
|
|
@@ -366,6 +368,7 @@ A estrutura do aplicativo é importante para garantir uma boa manutenção da su
|
|
|
366
368
|
|
|
367
369
|
```bash
|
|
368
370
|
.
|
|
371
|
+
├── i18n.ts
|
|
369
372
|
├── locales
|
|
370
373
|
│ ├── en
|
|
371
374
|
│ │ ├── home.json
|
|
@@ -376,11 +379,13 @@ A estrutura do aplicativo é importante para garantir uma boa manutenção da su
|
|
|
376
379
|
│ └── es
|
|
377
380
|
│ ├── home.json
|
|
378
381
|
│ └── navbar.json
|
|
379
|
-
├── i18n.ts
|
|
380
382
|
└── src
|
|
381
383
|
├── middleware.ts
|
|
382
384
|
├── app
|
|
383
|
-
│
|
|
385
|
+
│ ├── i18n
|
|
386
|
+
│ │ └── server.ts
|
|
387
|
+
│ └── [locale]
|
|
388
|
+
│ └── home.tsx
|
|
384
389
|
└── components
|
|
385
390
|
└── Navbar
|
|
386
391
|
└── index.tsx
|
|
@@ -395,9 +400,11 @@ A estrutura do aplicativo é importante para garantir uma boa manutenção da su
|
|
|
395
400
|
└── src
|
|
396
401
|
├── middleware.ts
|
|
397
402
|
├── app
|
|
398
|
-
│ └──
|
|
399
|
-
│
|
|
400
|
-
│ └──
|
|
403
|
+
│ └── [locale]
|
|
404
|
+
│ ├── layout.tsx
|
|
405
|
+
│ └── home
|
|
406
|
+
│ ├── index.tsx
|
|
407
|
+
│ └── index.content.ts
|
|
401
408
|
└── components
|
|
402
409
|
└── Navbar
|
|
403
410
|
├── index.tsx
|
|
@@ -525,8 +532,10 @@ export default async function LocaleLayout({
|
|
|
525
532
|
const messages = await getMessages();
|
|
526
533
|
const clientMessages = pick(messages, ["common", "about"]);
|
|
527
534
|
|
|
535
|
+
const rtlLocales = ["ar", "he", "fa", "ur"];
|
|
536
|
+
|
|
528
537
|
return (
|
|
529
|
-
<html lang={locale}>
|
|
538
|
+
<html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>
|
|
530
539
|
<body>
|
|
531
540
|
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
532
541
|
{children}
|
|
@@ -843,10 +852,11 @@ const ServerComponent = ({ count }: ServerComponentProps) => {
|
|
|
843
852
|
type ServerComponentProps = {
|
|
844
853
|
count: number;
|
|
845
854
|
t: (key: string) => string;
|
|
855
|
+
formatter: Intl.NumberFormat;
|
|
846
856
|
};
|
|
847
857
|
|
|
848
|
-
const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
849
|
-
const formatted =
|
|
858
|
+
const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {
|
|
859
|
+
const formatted = formatter.format(count);
|
|
850
860
|
|
|
851
861
|
return (
|
|
852
862
|
<div>
|
|
@@ -860,7 +870,7 @@ const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
|
860
870
|
> Como o componente do servidor não pode ser assíncrono, você precisa passar as traduções e a função formatadora como props.
|
|
861
871
|
>
|
|
862
872
|
> - `const t = await getTranslations("about.counter");`
|
|
863
|
-
> - `const
|
|
873
|
+
> - `const formatter = await getFormatter().then((formatter) => formatter.number());`
|
|
864
874
|
|
|
865
875
|
</TabItem>
|
|
866
876
|
<TabItem label="intlayer" value="intlayer">
|
|
@@ -173,9 +173,9 @@ Next.js предоставляет встроенную поддержку ин
|
|
|
173
173
|
|
|
174
174
|
Вот пример влияния оптимизации размера бандла с использованием `intlayer` в приложении на vite + react:
|
|
175
175
|
|
|
176
|
-
| Оптимизированный бандл
|
|
177
|
-
|
|
|
178
|
-
|  |  |
|
|
176
|
+
| Оптимизированный бандл | Неоптимизированный бандл |
|
|
177
|
+
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
178
|
+
|  |  |
|
|
179
179
|
|
|
180
180
|
---
|
|
181
181
|
|
|
@@ -348,25 +348,25 @@ Next.js предоставляет встроенную поддержку ин
|
|
|
348
348
|
|
|
349
349
|
```bash
|
|
350
350
|
.
|
|
351
|
-
├──
|
|
352
|
-
│ └── locales
|
|
353
|
-
│ ├── en
|
|
354
|
-
│ │ ├── home.json
|
|
355
|
-
│ │ └── navbar.json
|
|
356
|
-
│ ├── fr
|
|
357
|
-
│ │ ├── home.json
|
|
358
|
-
│ │ └── navbar.json
|
|
359
|
-
│ └── es
|
|
360
|
-
│ ├── home.json
|
|
361
|
-
│ └── navbar.json
|
|
362
|
-
├── next-i18next.config.js
|
|
351
|
+
├── i18n.config.ts
|
|
363
352
|
└── src
|
|
364
|
-
├──
|
|
353
|
+
├── locales
|
|
354
|
+
│ ├── en
|
|
355
|
+
│ │ ├── common.json
|
|
356
|
+
│ │ └── about.json
|
|
357
|
+
│ └── fr
|
|
358
|
+
│ ├── common.json
|
|
359
|
+
│ └── about.json
|
|
365
360
|
├── app
|
|
366
|
-
│
|
|
361
|
+
│ ├── i18n
|
|
362
|
+
│ │ └── server.ts
|
|
363
|
+
│ └── [locale]
|
|
364
|
+
│ ├── layout.tsx
|
|
365
|
+
│ └── about.tsx
|
|
367
366
|
└── components
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
├── I18nProvider.tsx
|
|
368
|
+
├── ClientComponent.tsx
|
|
369
|
+
└── ServerComponent.tsx
|
|
370
370
|
```
|
|
371
371
|
|
|
372
372
|
</TabItem>
|
|
@@ -374,6 +374,7 @@ Next.js предоставляет встроенную поддержку ин
|
|
|
374
374
|
|
|
375
375
|
```bash
|
|
376
376
|
.
|
|
377
|
+
├── i18n.ts
|
|
377
378
|
├── locales
|
|
378
379
|
│ ├── en
|
|
379
380
|
│ │ ├── home.json
|
|
@@ -384,11 +385,13 @@ Next.js предоставляет встроенную поддержку ин
|
|
|
384
385
|
│ └── es
|
|
385
386
|
│ ├── home.json
|
|
386
387
|
│ └── navbar.json
|
|
387
|
-
├── i18n.ts
|
|
388
388
|
└── src
|
|
389
389
|
├── middleware.ts
|
|
390
390
|
├── app
|
|
391
|
-
│
|
|
391
|
+
│ ├── i18n
|
|
392
|
+
│ │ └── server.ts
|
|
393
|
+
│ └── [locale]
|
|
394
|
+
│ └── home.tsx
|
|
392
395
|
└── components
|
|
393
396
|
└── Navbar
|
|
394
397
|
└── index.tsx
|
|
@@ -403,9 +406,11 @@ Next.js предоставляет встроенную поддержку ин
|
|
|
403
406
|
└── src
|
|
404
407
|
├── middleware.ts
|
|
405
408
|
├── app
|
|
406
|
-
│ └──
|
|
407
|
-
│
|
|
408
|
-
│ └──
|
|
409
|
+
│ └── [locale]
|
|
410
|
+
│ ├── layout.tsx
|
|
411
|
+
│ └── home
|
|
412
|
+
│ ├── index.tsx
|
|
413
|
+
│ └── index.content.ts
|
|
409
414
|
└── components
|
|
410
415
|
└── Navbar
|
|
411
416
|
├── index.tsx
|
|
@@ -533,8 +538,10 @@ export default async function LocaleLayout({
|
|
|
533
538
|
const messages = await getMessages();
|
|
534
539
|
const clientMessages = pick(messages, ["common", "about"]);
|
|
535
540
|
|
|
541
|
+
const rtlLocales = ["ar", "he", "fa", "ur"];
|
|
542
|
+
|
|
536
543
|
return (
|
|
537
|
-
<html lang={locale}>
|
|
544
|
+
<html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>
|
|
538
545
|
<body>
|
|
539
546
|
<NextIntlClientProvider locale={locale} messages={clientMessages}>
|
|
540
547
|
{children}
|
|
@@ -851,10 +858,11 @@ const ServerComponent = ({ count }: ServerComponentProps) => {
|
|
|
851
858
|
type ServerComponentProps = {
|
|
852
859
|
count: number;
|
|
853
860
|
t: (key: string) => string;
|
|
861
|
+
formatter: Intl.NumberFormat;
|
|
854
862
|
};
|
|
855
863
|
|
|
856
|
-
const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
857
|
-
const formatted =
|
|
864
|
+
const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {
|
|
865
|
+
const formatted = formatter.format(count);
|
|
858
866
|
|
|
859
867
|
return (
|
|
860
868
|
<div>
|
|
@@ -868,7 +876,7 @@ const ServerComponent = ({ t, count }: ServerComponentProps) => {
|
|
|
868
876
|
> Поскольку серверный компонент не может быть асинхронным, необходимо передавать переводы и функцию форматирования через пропсы.
|
|
869
877
|
>
|
|
870
878
|
> - `const t = await getTranslations("about.counter");`
|
|
871
|
-
> - `const
|
|
879
|
+
> - `const formatter = await getFormatter().then((formatter) => formatter.number());`
|
|
872
880
|
|
|
873
881
|
</TabItem>
|
|
874
882
|
<TabItem label="intlayer" value="intlayer">
|