@intlayer/docs 8.6.10 → 8.7.0-canary.1
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/i18n_using_next-i18next.md +1 -1
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/de/i18n_using_next-i18next.md +1 -1
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/en/i18n_using_next-i18next.md +1 -1
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/en-GB/i18n_using_next-i18next.md +1 -1
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/es/i18n_using_next-i18next.md +1 -1
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/fr/i18n_using_next-i18next.md +1 -1
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/hi/i18n_using_next-i18next.md +1 -1
- package/blog/id/i18n_using_next-i18next.md +1 -1
- package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/it/i18n_using_next-i18next.md +1 -1
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/ja/i18n_using_next-i18next.md +1 -1
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/ko/i18n_using_next-i18next.md +1 -1
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/pl/i18n_using_next-i18next.md +1 -1
- package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/pt/i18n_using_next-i18next.md +1 -1
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/ru/i18n_using_next-i18next.md +1 -1
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/blog/tr/i18n_using_next-i18next.md +1 -1
- package/blog/uk/i18n_using_next-i18next.md +1 -1
- package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/vi/i18n_using_next-i18next.md +1 -1
- package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
- package/blog/zh/i18n_using_next-i18next.md +1 -1
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- package/docs/ar/bundle_optimization.md +454 -0
- package/docs/ar/intlayer_with_next-i18next.md +1 -1
- package/docs/ar/intlayer_with_next-intl.md +1 -1
- package/docs/ar/intlayer_with_tanstack+solid.md +24 -5
- package/docs/ar/intlayer_with_tanstack.md +45 -68
- package/docs/bn/bundle_optimization.md +454 -0
- package/docs/cs/bundle_optimization.md +454 -0
- package/docs/de/bundle_optimization.md +454 -0
- package/docs/de/intlayer_with_next-i18next.md +1 -1
- package/docs/de/intlayer_with_next-intl.md +1 -1
- package/docs/de/intlayer_with_tanstack+solid.md +24 -5
- package/docs/de/intlayer_with_tanstack.md +45 -68
- package/docs/en/bundle_optimization.md +36 -8
- package/docs/en/intlayer_with_next-i18next.md +1 -1
- package/docs/en/intlayer_with_next-intl.md +1 -1
- package/docs/en/intlayer_with_tanstack+solid.md +24 -5
- package/docs/en/intlayer_with_tanstack.md +45 -68
- package/docs/en-GB/bundle_optimization.md +454 -0
- package/docs/en-GB/intlayer_with_next-i18next.md +1 -1
- package/docs/en-GB/intlayer_with_next-intl.md +1 -1
- package/docs/en-GB/intlayer_with_tanstack+solid.md +24 -5
- package/docs/en-GB/intlayer_with_tanstack.md +47 -70
- package/docs/es/bundle_optimization.md +454 -0
- package/docs/es/intlayer_with_next-i18next.md +1 -1
- package/docs/es/intlayer_with_next-intl.md +1 -1
- package/docs/es/intlayer_with_tanstack+solid.md +24 -5
- package/docs/es/intlayer_with_tanstack.md +45 -68
- package/docs/fr/bundle_optimization.md +454 -0
- package/docs/fr/intlayer_with_next-i18next.md +1 -1
- package/docs/fr/intlayer_with_next-intl.md +1 -1
- package/docs/fr/intlayer_with_tanstack+solid.md +24 -5
- package/docs/fr/intlayer_with_tanstack.md +45 -68
- package/docs/hi/bundle_optimization.md +454 -0
- package/docs/hi/intlayer_with_next-i18next.md +1 -1
- package/docs/hi/intlayer_with_next-intl.md +1 -1
- package/docs/hi/intlayer_with_tanstack+solid.md +24 -5
- package/docs/hi/intlayer_with_tanstack.md +45 -68
- package/docs/id/bundle_optimization.md +454 -0
- package/docs/id/intlayer_with_next-i18next.md +1 -1
- package/docs/id/intlayer_with_next-intl.md +1 -1
- package/docs/id/intlayer_with_tanstack+solid.md +24 -5
- package/docs/id/intlayer_with_tanstack.md +45 -68
- package/docs/it/bundle_optimization.md +454 -0
- package/docs/it/intlayer_with_next-i18next.md +1 -1
- package/docs/it/intlayer_with_next-intl.md +1 -1
- package/docs/it/intlayer_with_tanstack+solid.md +24 -5
- package/docs/it/intlayer_with_tanstack.md +45 -68
- package/docs/ja/bundle_optimization.md +454 -0
- package/docs/ja/intlayer_with_next-i18next.md +1 -1
- package/docs/ja/intlayer_with_next-intl.md +1 -1
- package/docs/ja/intlayer_with_tanstack+solid.md +24 -5
- package/docs/ja/intlayer_with_tanstack.md +45 -36
- package/docs/ko/bundle_optimization.md +454 -0
- package/docs/ko/intlayer_with_next-i18next.md +1 -1
- package/docs/ko/intlayer_with_next-intl.md +1 -1
- package/docs/ko/intlayer_with_tanstack+solid.md +24 -5
- package/docs/ko/intlayer_with_tanstack.md +45 -68
- package/docs/nl/bundle_optimization.md +454 -0
- package/docs/pl/bundle_optimization.md +454 -0
- package/docs/pl/intlayer_with_next-i18next.md +1 -1
- package/docs/pl/intlayer_with_next-intl.md +1 -1
- package/docs/pl/intlayer_with_tanstack+solid.md +24 -5
- package/docs/pl/intlayer_with_tanstack.md +45 -68
- package/docs/pt/bundle_optimization.md +454 -0
- package/docs/pt/intlayer_with_next-i18next.md +1 -1
- package/docs/pt/intlayer_with_next-intl.md +1 -1
- package/docs/pt/intlayer_with_tanstack+solid.md +24 -5
- package/docs/pt/intlayer_with_tanstack.md +45 -68
- package/docs/ru/bundle_optimization.md +454 -0
- package/docs/ru/intlayer_with_next-i18next.md +1 -1
- package/docs/ru/intlayer_with_next-intl.md +1 -1
- package/docs/ru/intlayer_with_tanstack+solid.md +24 -5
- package/docs/ru/intlayer_with_tanstack.md +45 -68
- package/docs/tr/bundle_optimization.md +454 -0
- package/docs/tr/intlayer_with_next-i18next.md +1 -1
- package/docs/tr/intlayer_with_next-intl.md +1 -1
- package/docs/tr/intlayer_with_tanstack+solid.md +24 -5
- package/docs/tr/intlayer_with_tanstack.md +45 -68
- package/docs/uk/bundle_optimization.md +454 -0
- package/docs/uk/intlayer_with_next-i18next.md +1 -1
- package/docs/uk/intlayer_with_next-intl.md +1 -1
- package/docs/uk/intlayer_with_tanstack+solid.md +24 -5
- package/docs/uk/intlayer_with_tanstack.md +45 -68
- package/docs/ur/bundle_optimization.md +454 -0
- package/docs/vi/bundle_optimization.md +454 -0
- package/docs/vi/intlayer_with_next-i18next.md +1 -1
- package/docs/vi/intlayer_with_next-intl.md +1 -1
- package/docs/vi/intlayer_with_tanstack+solid.md +24 -5
- package/docs/vi/intlayer_with_tanstack.md +45 -68
- package/docs/zh/bundle_optimization.md +454 -0
- package/docs/zh/intlayer_with_next-i18next.md +1 -1
- package/docs/zh/intlayer_with_next-intl.md +1 -1
- package/docs/zh/intlayer_with_tanstack+solid.md +24 -5
- package/docs/zh/intlayer_with_tanstack.md +45 -68
- package/package.json +7 -7
|
@@ -225,9 +225,7 @@ function RootDocument({ children }: { children: ReactNode }) {
|
|
|
225
225
|
<HeadContent />
|
|
226
226
|
</head>
|
|
227
227
|
<body>
|
|
228
|
-
<IntlayerProvider locale={locale}>
|
|
229
|
-
{children}
|
|
230
|
-
</IntlayerProvider>
|
|
228
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
231
229
|
<Scripts />
|
|
232
230
|
</body>
|
|
233
231
|
</html>
|
|
@@ -326,30 +324,20 @@ import { getPrefix } from "intlayer";
|
|
|
326
324
|
|
|
327
325
|
export const LOCALE_ROUTE = "{-$locale}" as const;
|
|
328
326
|
|
|
329
|
-
|
|
330
|
-
export type RemoveLocaleParam<T> = T extends string
|
|
331
|
-
? RemoveLocaleFromString<T>
|
|
332
|
-
: T;
|
|
327
|
+
export type To = StripLocalePrefix<LinkComponentProps["to"]>;
|
|
333
328
|
|
|
334
|
-
export type
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
329
|
+
export type StripLocalePrefix<T extends string | undefined> = T extends
|
|
330
|
+
| `/${typeof LOCALE_ROUTE}/`
|
|
331
|
+
| `/${typeof LOCALE_ROUTE}`
|
|
332
|
+
? "/"
|
|
333
|
+
: T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
|
|
334
|
+
? `/${Rest}`
|
|
335
|
+
: T;
|
|
338
336
|
|
|
339
337
|
type LocalizedLinkProps = {
|
|
340
338
|
to?: To;
|
|
341
339
|
} & Omit<LinkComponentProps, "to">;
|
|
342
340
|
|
|
343
|
-
// 헬퍼
|
|
344
|
-
type RemoveAll<
|
|
345
|
-
S extends string,
|
|
346
|
-
Sub extends string,
|
|
347
|
-
> = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;
|
|
348
|
-
|
|
349
|
-
type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<
|
|
350
|
-
RemoveAll<S, typeof LOCALE_ROUTE>
|
|
351
|
-
>;
|
|
352
|
-
|
|
353
341
|
export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
|
|
354
342
|
const { locale } = useLocale();
|
|
355
343
|
const { localePrefix } = getPrefix(locale);
|
|
@@ -378,26 +366,26 @@ export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
|
|
|
378
366
|
import { useNavigate } from "@tanstack/react-router";
|
|
379
367
|
import { getPrefix } from "intlayer";
|
|
380
368
|
import { useLocale } from "react-intlayer";
|
|
381
|
-
import {
|
|
369
|
+
import type { StripLocalePrefix } from "@/components/localized-link";
|
|
382
370
|
import type { FileRouteTypes } from "@/routeTree.gen";
|
|
383
371
|
|
|
384
|
-
type
|
|
385
|
-
|
|
386
|
-
| `/${typeof LOCALE_ROUTE}/`
|
|
387
|
-
? "/"
|
|
388
|
-
: T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
|
|
389
|
-
? `/${Rest}`
|
|
390
|
-
: never;
|
|
372
|
+
type NavigateFn = ReturnType<typeof useNavigate>;
|
|
373
|
+
type BaseNavigateOptions = Parameters<NavigateFn>[0];
|
|
391
374
|
|
|
392
375
|
type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;
|
|
393
376
|
|
|
394
|
-
type
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
377
|
+
export type LocalizedNavigateOptions = Omit<
|
|
378
|
+
BaseNavigateOptions,
|
|
379
|
+
"to" | "params"
|
|
380
|
+
> & {
|
|
381
|
+
to: LocalizedTo;
|
|
382
|
+
params?: Omit<NonNullable<BaseNavigateOptions["params"]>, "locale">;
|
|
399
383
|
};
|
|
400
384
|
|
|
385
|
+
type LocalizedNavigate = (
|
|
386
|
+
options: LocalizedNavigateOptions
|
|
387
|
+
) => ReturnType<NavigateFn>;
|
|
388
|
+
|
|
401
389
|
export const useLocalizedNavigate = () => {
|
|
402
390
|
const navigate = useNavigate();
|
|
403
391
|
|
|
@@ -444,38 +432,6 @@ import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";
|
|
|
444
432
|
|
|
445
433
|
export const Route = createFileRoute("/{-$locale}/")({
|
|
446
434
|
component: RouteComponent,
|
|
447
|
-
head: ({ params }) => {
|
|
448
|
-
const { locale } = params;
|
|
449
|
-
const path = "/"; // The path for this route
|
|
450
|
-
|
|
451
|
-
const metaContent = getIntlayer("app", locale);
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
links: [
|
|
455
|
-
// Canonical link: Points to the current localized page
|
|
456
|
-
{ rel: "canonical", href: getLocalizedUrl(path, locale) },
|
|
457
|
-
|
|
458
|
-
// Hreflang: Tell Google about all localized versions
|
|
459
|
-
...localeMap(({ locale: mapLocale }) => ({
|
|
460
|
-
rel: "alternate",
|
|
461
|
-
hrefLang: mapLocale,
|
|
462
|
-
href: getLocalizedUrl(path, mapLocale),
|
|
463
|
-
})),
|
|
464
|
-
|
|
465
|
-
// x-default: For users in unmatched languages
|
|
466
|
-
// Define the default fallback locale (usually your primary language)
|
|
467
|
-
{
|
|
468
|
-
rel: "alternate",
|
|
469
|
-
hrefLang: "x-default",
|
|
470
|
-
href: getLocalizedUrl(path, defaultLocale),
|
|
471
|
-
},
|
|
472
|
-
],
|
|
473
|
-
meta: [
|
|
474
|
-
{ title: metaContent.title },
|
|
475
|
-
{ name: "description", content: metaContent.meta.description },
|
|
476
|
-
],
|
|
477
|
-
};
|
|
478
|
-
},
|
|
479
435
|
});
|
|
480
436
|
|
|
481
437
|
function RouteComponent() {
|
|
@@ -630,12 +586,33 @@ export const Route = createFileRoute("/{-$locale}/")({
|
|
|
630
586
|
component: RouteComponent,
|
|
631
587
|
head: ({ params }) => {
|
|
632
588
|
const { locale } = params;
|
|
633
|
-
const
|
|
589
|
+
const path = "/"; // The path for this route
|
|
590
|
+
|
|
591
|
+
const metaContent = getIntlayer("app", locale);
|
|
634
592
|
|
|
635
593
|
return {
|
|
594
|
+
links: [
|
|
595
|
+
// Canonical link: Points to the current localized page
|
|
596
|
+
{ rel: "canonical", href: getLocalizedUrl(path, locale) },
|
|
597
|
+
|
|
598
|
+
// Hreflang: Tell Google about all localized versions
|
|
599
|
+
...localeMap(({ locale: mapLocale }) => ({
|
|
600
|
+
rel: "alternate",
|
|
601
|
+
hrefLang: mapLocale,
|
|
602
|
+
href: getLocalizedUrl(path, mapLocale),
|
|
603
|
+
})),
|
|
604
|
+
|
|
605
|
+
// x-default: For users in unmatched languages
|
|
606
|
+
// Define the default fallback locale (usually your primary language)
|
|
607
|
+
{
|
|
608
|
+
rel: "alternate",
|
|
609
|
+
hrefLang: "x-default",
|
|
610
|
+
href: getLocalizedUrl(path, defaultLocale),
|
|
611
|
+
},
|
|
612
|
+
],
|
|
636
613
|
meta: [
|
|
637
614
|
{ title: metaContent.title },
|
|
638
|
-
{
|
|
615
|
+
{ name: "description", content: metaContent.meta.description },
|
|
639
616
|
],
|
|
640
617
|
};
|
|
641
618
|
},
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-11-25
|
|
3
|
+
updatedAt: 2026-04-08
|
|
4
|
+
title: Optimalisatie van i18n-bundelgrootte en prestaties
|
|
5
|
+
description: Verminder de bundelgrootte van uw applicatie door internationaliseringsinhoud (i18n) te optimaliseren. Leer hoe u tree shaking en lazy loading kunt inzetten voor woordenboeken met Intlayer.
|
|
6
|
+
keywords:
|
|
7
|
+
- Bundeloptimalisatie
|
|
8
|
+
- Inhoudsautomatisering
|
|
9
|
+
- Dynamische inhoud
|
|
10
|
+
- Intlayer
|
|
11
|
+
- Next.js
|
|
12
|
+
- JavaScript
|
|
13
|
+
- React
|
|
14
|
+
slugs:
|
|
15
|
+
- doc
|
|
16
|
+
- concept
|
|
17
|
+
- bundle-optimization
|
|
18
|
+
history:
|
|
19
|
+
- version: 8.7.0
|
|
20
|
+
date: 2026-04-08
|
|
21
|
+
changes: "Opties `minify` en `purge` toegevoegd aan de build-configuratie"
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Optimalisatie van i18n-bundelgrootte en prestaties
|
|
25
|
+
|
|
26
|
+
Een van de meest voorkomende uitdagingen bij traditionele i18n-oplossingen die afhankelijk zijn van JSON-bestanden, is het beheren van de omvang van de inhoud. Als ontwikkelaars de inhoud niet handmatig scheiden in namespaces, downloaden gebruikers vaak vertalingen voor elke pagina en mogelijk elke taal, alleen maar om een enkele pagina te bekijken.
|
|
27
|
+
|
|
28
|
+
Bijvoorbeeld, een applicatie met 10 pagina's vertaald in 10 talen kan ertoe leiden dat een gebruiker de inhoud van 100 pagina's downloadt, ook al hebben ze er maar **één** nodig (de huidige pagina in de huidige taal). Dit leidt tot verspilling van bandbreedte en langzamere laadtijden.
|
|
29
|
+
|
|
30
|
+
**Intlayer lost dit probleem op via optimalisatie tijdens de build.** Het analyseert uw code om te detecteren welke woordenboeken daadwerkelijk per component worden gebruikt en injecteert alleen de noodzakelijke inhoud opnieuw in uw bundel.
|
|
31
|
+
|
|
32
|
+
## Inhoudsopgave
|
|
33
|
+
|
|
34
|
+
<TOC />
|
|
35
|
+
|
|
36
|
+
## Scan uw bundel
|
|
37
|
+
|
|
38
|
+
Het analyseren van uw bundel is de eerste stap bij het identificeren van "zware" JSON-bestanden en mogelijkheden voor code-splitting. Deze tools genereren een visuele treemap van de gecompileerde code van uw applicatie, zodat u precies kunt zien welke bibliotheken de meeste ruimte in beslag nemen.
|
|
39
|
+
|
|
40
|
+
<Tabs>
|
|
41
|
+
<Tab value="vite">
|
|
42
|
+
|
|
43
|
+
### Vite / Rollup
|
|
44
|
+
|
|
45
|
+
Vite gebruikt Rollup onder de motorkap. De `rollup-plugin-visualizer` genereert een interactief HTML-bestand dat de grootte van elke module in uw graaf toont.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install -D rollup-plugin-visualizer
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```typescript fileName="vite.config.ts"
|
|
52
|
+
import { defineConfig } from "vite";
|
|
53
|
+
import { visualizer } from "rollup-plugin-visualizer";
|
|
54
|
+
|
|
55
|
+
export default defineConfig({
|
|
56
|
+
plugins: [
|
|
57
|
+
visualizer({
|
|
58
|
+
open: true, // Open het rapport automatisch in je browser
|
|
59
|
+
filename: "stats.html",
|
|
60
|
+
gzipSize: true,
|
|
61
|
+
brotliSize: true,
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
</Tab>
|
|
68
|
+
<Tab value="nextjs (turbopack)">
|
|
69
|
+
|
|
70
|
+
### Next.js (Turbopack)
|
|
71
|
+
|
|
72
|
+
Voor projecten die de App Router en Turbopack gebruiken, biedt Next.js een ingebouwde experimentele analyzer die geen extra afhankelijkheden vereist.
|
|
73
|
+
|
|
74
|
+
```bash packageManager='npm'
|
|
75
|
+
npx next experimental-analyze
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash packageManager='yarn'
|
|
79
|
+
yarn next experimental-analyze
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash packageManager='pnpm'
|
|
83
|
+
pnpm next experimental-analyze
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```bash packageManager='bun'
|
|
87
|
+
bun next experimental-analyze
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
</Tab>
|
|
91
|
+
<Tab value="nextjs (Webpack)">
|
|
92
|
+
|
|
93
|
+
### Next.js (Webpack)
|
|
94
|
+
|
|
95
|
+
Als u de standaard Webpack-bundler in Next.js gebruikt, gebruik dan de officiële bundel-analyzer. Activeer deze door een omgevingsvariabele in te stellen tijdens uw build.
|
|
96
|
+
|
|
97
|
+
```bash packageManager='npm'
|
|
98
|
+
npm install -D @next/bundle-analyzer
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```bash packageManager='yarn'
|
|
102
|
+
yarn add -D @next/bundle-analyzer
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```bash packageManager='pnpm'
|
|
106
|
+
pnpm add -D @next/bundle-analyzer
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```bash packageManager='bun'
|
|
110
|
+
bun add -d @next/bundle-analyzer
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```javascript fileName="next.config.js"
|
|
114
|
+
const withBundleAnalyzer = require("@next/bundle-analyzer")({
|
|
115
|
+
enabled: process.env.ANALYZE === "true",
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
module.exports = withBundleAnalyzer({
|
|
119
|
+
// Uw Next.js configuratie
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Gebruik:**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
ANALYZE=true npm run build
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
</Tab>
|
|
130
|
+
<Tab value="Webpack (CRA / Angular / etc)">
|
|
131
|
+
|
|
132
|
+
### Standaard Webpack
|
|
133
|
+
|
|
134
|
+
Voor Create React App (ejected), Angular of aangepaste Webpack-setups, gebruikt u de industriestandaard `webpack-bundle-analyzer`.
|
|
135
|
+
|
|
136
|
+
```bash packageManager='npm'
|
|
137
|
+
npm install -D webpack-bundle-analyzer
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```bash packageManager='yarn'
|
|
141
|
+
yarn add -D webpack-bundle-analyzer
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```bash packageManager='pnpm'
|
|
145
|
+
pnpm add -D webpack-bundle-analyzer
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```bash packageManager='bun'
|
|
149
|
+
bun add -d webpack-bundle-analyzer
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```typescript fileName="webpack.config.ts
|
|
153
|
+
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
|
|
154
|
+
|
|
155
|
+
export default {
|
|
156
|
+
plugins: [
|
|
157
|
+
new BundleAnalyzerPlugin({
|
|
158
|
+
analyzerMode: "static",
|
|
159
|
+
reportFilename: "bundle-analyzer.html",
|
|
160
|
+
openAnalyzer: false,
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
</Tab>
|
|
167
|
+
</Tabs>
|
|
168
|
+
|
|
169
|
+
## Hoe het werkt
|
|
170
|
+
|
|
171
|
+
Intlayer gebruikt een **per-component aanpak**. In tegenstelling tot globale JSON-bestanden, wordt uw inhoud gedefinieerd naast of binnen uw componenten. Tijdens het build-proces zal Intlayer:
|
|
172
|
+
|
|
173
|
+
1. Uw code **analyseren** om `useIntlayer`-aanroepen te vinden.
|
|
174
|
+
2. De bijbehorende woordenboekinhoud **bouwen**.
|
|
175
|
+
3. De `useIntlayer`-aanroep **vervangen** door geoptimaliseerde code op basis van uw configuratie.
|
|
176
|
+
|
|
177
|
+
Dit zorgt ervoor dat:
|
|
178
|
+
|
|
179
|
+
- Als een component niet wordt geïmporteerd, de inhoud ervan niet in de bundel wordt opgenomen (Dead Code Elimination).
|
|
180
|
+
- Als een component lazy-loaded is, de inhoud ervan ook lazy-loaded is.
|
|
181
|
+
|
|
182
|
+
## Installatie per platform
|
|
183
|
+
|
|
184
|
+
<Tabs>
|
|
185
|
+
<Tab value="nextjs">
|
|
186
|
+
|
|
187
|
+
### Next.js
|
|
188
|
+
|
|
189
|
+
Next.js vereist de `@intlayer/swc` plugin om de transformatie af te handelen, aangezien Next.js SWC gebruikt voor builds.
|
|
190
|
+
|
|
191
|
+
> Deze plugin is niet standaard geïnstalleerd omdat SWC-plugins nog experimenteel zijn voor Next.js. Dit kan in de toekomst veranderen.
|
|
192
|
+
|
|
193
|
+
```bash packageManager="npm"
|
|
194
|
+
npm install -D @intlayer/swc
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```bash packageManager="yarn"
|
|
198
|
+
yarn add -D @intlayer/swc
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```bash packageManager="pnpm"
|
|
202
|
+
pnpm add -D @intlayer/swc
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```bash packageManager="bun"
|
|
206
|
+
bun add -d @intlayer/swc
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Eenmaal geïnstalleerd, zal Intlayer de plugin automatisch detecteren en gebruiken.
|
|
210
|
+
|
|
211
|
+
</Tab>
|
|
212
|
+
<Tab value="vite">
|
|
213
|
+
|
|
214
|
+
### Vite
|
|
215
|
+
|
|
216
|
+
Vite gebruikt de `@intlayer/babel` plugin die als afhankelijkheid van `vite-intlayer` is opgenomen. De optimalisatie is standaard ingeschakeld. Verder hoeft u niets te doen.
|
|
217
|
+
|
|
218
|
+
</Tab>
|
|
219
|
+
<Tab value="webpack">
|
|
220
|
+
|
|
221
|
+
### Webpack
|
|
222
|
+
|
|
223
|
+
Om bundeloptimalisatie met Intlayer op Webpack in te schakelen, moet u de juiste Babel (`@intlayer/babel`) of SWC (`@intlayer/swc`) plugin installeren en configureren.
|
|
224
|
+
|
|
225
|
+
```bash packageManager="npm"
|
|
226
|
+
npm install -D @intlayer/babel
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```bash packageManager="yarn"
|
|
230
|
+
yarn add -D @intlayer/babel
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```bash packageManager="pnpm"
|
|
234
|
+
pnpm add -D @intlayer/babel
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```bash packageManager="bun"
|
|
238
|
+
bun add -d @intlayer/babel
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```typescript fileName="babel.config.js"
|
|
242
|
+
const {
|
|
243
|
+
getOptimizePluginOptions,
|
|
244
|
+
intlayerOptimizeBabelPlugin,
|
|
245
|
+
} = require("@intlayer/babel");
|
|
246
|
+
|
|
247
|
+
module.exports = {
|
|
248
|
+
plugins: [[intlayerOptimizeBabelPlugin, getOptimizePluginOptions()]],
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
</Tab>
|
|
253
|
+
</Tabs>
|
|
254
|
+
|
|
255
|
+
## Configuratie
|
|
256
|
+
|
|
257
|
+
U kunt bepalen hoe Intlayer uw bundel optimaliseert via de `build` eigenschap in uw `intlayer.config.ts`.
|
|
258
|
+
|
|
259
|
+
```typescript fileName="intlayer.config.ts"
|
|
260
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
261
|
+
|
|
262
|
+
const config: IntlayerConfig = {
|
|
263
|
+
internationalization: {
|
|
264
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
265
|
+
defaultLocale: Locales.ENGLISH,
|
|
266
|
+
},
|
|
267
|
+
dictionary: {
|
|
268
|
+
importMode: "dynamic",
|
|
269
|
+
},
|
|
270
|
+
build: {
|
|
271
|
+
/**
|
|
272
|
+
* Minificeer de woordenboeken om de bundelgrootte te verkleinen.
|
|
273
|
+
*/
|
|
274
|
+
minify: true;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Verwijder ongebruikte sleutels in woordenboeken (purge)
|
|
278
|
+
*/
|
|
279
|
+
purge: true;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Geeft aan of de build TypeScript-typen moet controleren
|
|
283
|
+
*/
|
|
284
|
+
checkTypes: false;
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export default config;
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
> Het wordt in de meeste gevallen aanbevolen om de standaardoptie voor `optimize` te behouden.
|
|
292
|
+
|
|
293
|
+
> Zie de configuratie-doc voor meer details: [Configuratie](https://github.com/aymericzip/intlayer/blob/main/docs/docs/nl/configuration.md)
|
|
294
|
+
|
|
295
|
+
### Build-opties
|
|
296
|
+
|
|
297
|
+
De volgende opties zijn beschikbaar onder het `build` configuratie-object:
|
|
298
|
+
|
|
299
|
+
| Eigenschap | Type | Standaard | Beschrijving |
|
|
300
|
+
| :------------- | :-------- | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
301
|
+
| **`optimize`** | `boolean` | `undefined` | Bepaalt of build-optimalisatie is ingeschakeld. Indien `true`, vervangt Intlayer woordenboekaanroepen door geoptimaliseerde injecties. Indien `false`, is optimalisatie uitgeschakeld. Ideaal ingesteld op `true` in prod. |
|
|
302
|
+
| **`minify`** | `boolean` | `false` | Of de woordenboeken moeten worden geminificeerd om de bundelgrootte te verkleinen. |
|
|
303
|
+
| **`purge`** | `boolean` | `false` | Of de ongebruikte sleutels in woordenboeken moeten worden verwijderd. |
|
|
304
|
+
|
|
305
|
+
### Minificatie
|
|
306
|
+
|
|
307
|
+
Het minificeren van woordenboeken verwijdert onnodige witruimte, opmerkingen en vermindert de omvang van de JSON-inhoud. Dit is vooral handig voor grote woordenboeken.
|
|
308
|
+
|
|
309
|
+
```typescript fileName="intlayer.config.ts"
|
|
310
|
+
import type { IntlayerConfig } from "intlayer";
|
|
311
|
+
|
|
312
|
+
const config: IntlayerConfig = {
|
|
313
|
+
build: {
|
|
314
|
+
minify: true,
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
export default config;
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
> Opmerking: Minificatie wordt genegeerd als `optimize` is uitgeschakeld of als de Visual Editor is ingeschakeld (omdat de editor de volledige inhoud nodig heeft om bewerkingen toe te staan).
|
|
322
|
+
|
|
323
|
+
### Purging (Opschonen)
|
|
324
|
+
|
|
325
|
+
Purging zorgt ervoor dat alleen de sleutels die daadwerkelijk in uw code worden gebruikt, worden opgenomen in de uiteindelijke woordenboekbundel. Dit kan de omvang van uw bundel aanzienlijk verkleinen als u grote woordenboeken heeft met veel sleutels die niet in elk deel van uw applicatie worden gebruikt.
|
|
326
|
+
|
|
327
|
+
```typescript fileName="intlayer.config.ts"
|
|
328
|
+
import type { IntlayerConfig } from "intlayer";
|
|
329
|
+
|
|
330
|
+
const config: IntlayerConfig = {
|
|
331
|
+
build: {
|
|
332
|
+
purge: true,
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
export default config;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
> Opmerking: Purging wordt genegeerd als `optimize` is uitgeschakeld.
|
|
340
|
+
|
|
341
|
+
### Import Mode
|
|
342
|
+
|
|
343
|
+
Voor grote applicaties met meerdere pagina's en locales kunnen uw JSON-bestanden een aanzienlijk deel van uw bundelgrootte uitmaken. Met Intlayer kunt u bepalen hoe woordenboeken worden geladen.
|
|
344
|
+
|
|
345
|
+
De import mode kan standaard globaal worden gedefinieerd in uw `intlayer.config.ts` bestand.
|
|
346
|
+
|
|
347
|
+
```typescript fileName="intlayer.config.ts"
|
|
348
|
+
import type { IntlayerConfig } from "intlayer";
|
|
349
|
+
|
|
350
|
+
const config: IntlayerConfig = {
|
|
351
|
+
build: {
|
|
352
|
+
minify: true,
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
export default config;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Evenals voor elk woordenboek in uw `.content.{{ts|tsx|js|jsx|mjs|cjs|json|jsonc|json5}}` bestanden.
|
|
360
|
+
|
|
361
|
+
```ts
|
|
362
|
+
import { type Dictionary, t } from "intlayer";
|
|
363
|
+
|
|
364
|
+
const appContent: Dictionary = {
|
|
365
|
+
key: "app",
|
|
366
|
+
importMode: "dynamic", // Overschrijf de standaard import mode
|
|
367
|
+
content: {
|
|
368
|
+
// ...
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
export default appContent;
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
| Eigenschap | Type | Standaard | Beschrijving |
|
|
376
|
+
| :--------------- | :--------------------------------- | :--------- | :---------------------------------------------------------------------------------------------------------------------------------- |
|
|
377
|
+
| **`importMode`** | `'static'`, `'dynamic'`, `'fetch'` | `'static'` | **Verouderd**: Gebruik in plaats daarvan `dictionary.importMode`. Bepaalt hoe woordenboeken worden geladen (zie details hieronder). |
|
|
378
|
+
|
|
379
|
+
De `importMode` instelling bepaalt hoe de woordenboekinhoud in uw component wordt geïnjecteerd.
|
|
380
|
+
U kunt dit globaal definiëren in het `intlayer.config.ts` bestand onder het `dictionary` object, of u kunt het overschrijven voor een specifiek woordenboek in het bijbehorende `.content.ts` bestand.
|
|
381
|
+
|
|
382
|
+
### 1. Statische Modus (`default`)
|
|
383
|
+
|
|
384
|
+
In de statische modus vervangt Intlayer `useIntlayer` door `useDictionary` en injecteert het woordenboek rechtstreeks in de JavaScript-bundel.
|
|
385
|
+
|
|
386
|
+
- **Voordelen:** Directe rendering (synchroon), nul extra netwerkverzoeken tijdens hydratatie.
|
|
387
|
+
- **Nadelen:** De bundel bevat vertalingen voor **alle** beschikbare talen voor dat specifieke component.
|
|
388
|
+
- **Beste voor:** Single Page Applications (SPA).
|
|
389
|
+
|
|
390
|
+
**Voorbeeld van getransformeerde code:**
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
// Uw code
|
|
394
|
+
const content = useIntlayer("my-key");
|
|
395
|
+
|
|
396
|
+
// Geoptimaliseerde code (Statisch)
|
|
397
|
+
const content = useDictionary({
|
|
398
|
+
key: "my-key",
|
|
399
|
+
content: {
|
|
400
|
+
nodeType: "translation",
|
|
401
|
+
translation: {
|
|
402
|
+
en: "My title",
|
|
403
|
+
fr: "Mon titre",
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 2. Dynamische Modus
|
|
410
|
+
|
|
411
|
+
In de dynamische modus vervangt Intlayer `useIntlayer` door `useDictionaryAsync`. Dit maakt gebruik van `import()` (Suspense-achtig mechanisme) om specifiek de JSON voor de huidige locale lazy te laden.
|
|
412
|
+
|
|
413
|
+
- **Voordelen:** **Tree shaking op locale-niveau.** Een gebruiker die de Engelse versie bekijkt, downloadt _alleen_ het Engelse woordenboek. Het Franse woordenboek wordt nooit geladen.
|
|
414
|
+
- **Nadelen:** Activeert een netwerkverzoek (asset fetch) per component tijdens hydratatie.
|
|
415
|
+
- **Beste voor:** Grote tekstblokken, artikelen of applicaties die veel talen ondersteunen waarbij bundelgrootte kritiek is.
|
|
416
|
+
|
|
417
|
+
**Voorbeeld van getransformeerde code:**
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
// Uw code
|
|
421
|
+
const content = useIntlayer("my-key");
|
|
422
|
+
|
|
423
|
+
// Geoptimaliseerde code (Dynamisch)
|
|
424
|
+
const content = useDictionaryAsync({
|
|
425
|
+
en: () =>
|
|
426
|
+
import(".intlayer/dynamic_dictionary/my-key/en.json").then(
|
|
427
|
+
(mod) => mod.default
|
|
428
|
+
),
|
|
429
|
+
fr: () =>
|
|
430
|
+
import(".intlayer/dynamic_dictionary/my-key/fr.json").then(
|
|
431
|
+
(mod) => mod.default
|
|
432
|
+
),
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
> Wanneer u `importMode: 'dynamic'` gebruikt en u heeft 100 componenten die `useIntlayer` op een enkele pagina gebruiken, zal de browser 100 afzonderlijke fetches proberen. Om deze "waterval" van verzoeken te vermijden, groepeert u de inhoud in minder `.content` bestanden (bijv. één woordenboek per paginasectie) in plaats van één per atoomcomponent.
|
|
437
|
+
|
|
438
|
+
### 3. Fetch Mode
|
|
439
|
+
|
|
440
|
+
Gedraagt zich vergelijkbaar met de dynamische modus, maar probeert eerst woordenboeken op te halen uit de Intlayer Live Sync API. Als de API-aanroep mislukt of de inhoud niet is gemarkeerd voor live updates, valt het terug op de dynamische import.
|
|
441
|
+
|
|
442
|
+
> Zie CMS-documentatie voor meer details: [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/nl/intlayer_CMS.md)
|
|
443
|
+
|
|
444
|
+
> In fetch mode kunnen purging en minificatie niet worden gebruikt.
|
|
445
|
+
|
|
446
|
+
## Samenvatting: Statisch vs Dynamisch
|
|
447
|
+
|
|
448
|
+
| Functie | Statische Modus | Dynamische Modus |
|
|
449
|
+
| :------------------- | :------------------------------------------- | :---------------------------------- |
|
|
450
|
+
| **JS-bundelgrootte** | Groter (bevat alle talen voor het component) | Kleinste (alleen code, geen inhoud) |
|
|
451
|
+
| **Initiële Load** | Direct (inhoud zit in bundel) | Lichte vertraging (haalt JSON op) |
|
|
452
|
+
| **Netwerkverzoeken** | 0 extra verzoeken | 1 verzoek per woordenboek |
|
|
453
|
+
| **Tree Shaking** | Component-niveau | Component-niveau + Locale-niveau |
|
|
454
|
+
| **Beste Use Case** | UI-componenten, kleine apps | Pagina's met veel tekst, veel talen |
|