@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.
Files changed (129) hide show
  1. package/blog/ar/i18n_using_next-i18next.md +1 -1
  2. package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  3. package/blog/de/i18n_using_next-i18next.md +1 -1
  4. package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  5. package/blog/en/i18n_using_next-i18next.md +1 -1
  6. package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  7. package/blog/en-GB/i18n_using_next-i18next.md +1 -1
  8. package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  9. package/blog/es/i18n_using_next-i18next.md +1 -1
  10. package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  11. package/blog/fr/i18n_using_next-i18next.md +1 -1
  12. package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  13. package/blog/hi/i18n_using_next-i18next.md +1 -1
  14. package/blog/id/i18n_using_next-i18next.md +1 -1
  15. package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  16. package/blog/it/i18n_using_next-i18next.md +1 -1
  17. package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  18. package/blog/ja/i18n_using_next-i18next.md +1 -1
  19. package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  20. package/blog/ko/i18n_using_next-i18next.md +1 -1
  21. package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  22. package/blog/pl/i18n_using_next-i18next.md +1 -1
  23. package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  24. package/blog/pt/i18n_using_next-i18next.md +1 -1
  25. package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  26. package/blog/ru/i18n_using_next-i18next.md +1 -1
  27. package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  28. package/blog/tr/i18n_using_next-i18next.md +1 -1
  29. package/blog/uk/i18n_using_next-i18next.md +1 -1
  30. package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  31. package/blog/vi/i18n_using_next-i18next.md +1 -1
  32. package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +2 -2
  33. package/blog/zh/i18n_using_next-i18next.md +1 -1
  34. package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  35. package/docs/ar/bundle_optimization.md +454 -0
  36. package/docs/ar/intlayer_with_next-i18next.md +1 -1
  37. package/docs/ar/intlayer_with_next-intl.md +1 -1
  38. package/docs/ar/intlayer_with_tanstack+solid.md +24 -5
  39. package/docs/ar/intlayer_with_tanstack.md +45 -68
  40. package/docs/bn/bundle_optimization.md +454 -0
  41. package/docs/cs/bundle_optimization.md +454 -0
  42. package/docs/de/bundle_optimization.md +454 -0
  43. package/docs/de/intlayer_with_next-i18next.md +1 -1
  44. package/docs/de/intlayer_with_next-intl.md +1 -1
  45. package/docs/de/intlayer_with_tanstack+solid.md +24 -5
  46. package/docs/de/intlayer_with_tanstack.md +45 -68
  47. package/docs/en/bundle_optimization.md +36 -8
  48. package/docs/en/intlayer_with_next-i18next.md +1 -1
  49. package/docs/en/intlayer_with_next-intl.md +1 -1
  50. package/docs/en/intlayer_with_tanstack+solid.md +24 -5
  51. package/docs/en/intlayer_with_tanstack.md +45 -68
  52. package/docs/en-GB/bundle_optimization.md +454 -0
  53. package/docs/en-GB/intlayer_with_next-i18next.md +1 -1
  54. package/docs/en-GB/intlayer_with_next-intl.md +1 -1
  55. package/docs/en-GB/intlayer_with_tanstack+solid.md +24 -5
  56. package/docs/en-GB/intlayer_with_tanstack.md +47 -70
  57. package/docs/es/bundle_optimization.md +454 -0
  58. package/docs/es/intlayer_with_next-i18next.md +1 -1
  59. package/docs/es/intlayer_with_next-intl.md +1 -1
  60. package/docs/es/intlayer_with_tanstack+solid.md +24 -5
  61. package/docs/es/intlayer_with_tanstack.md +45 -68
  62. package/docs/fr/bundle_optimization.md +454 -0
  63. package/docs/fr/intlayer_with_next-i18next.md +1 -1
  64. package/docs/fr/intlayer_with_next-intl.md +1 -1
  65. package/docs/fr/intlayer_with_tanstack+solid.md +24 -5
  66. package/docs/fr/intlayer_with_tanstack.md +45 -68
  67. package/docs/hi/bundle_optimization.md +454 -0
  68. package/docs/hi/intlayer_with_next-i18next.md +1 -1
  69. package/docs/hi/intlayer_with_next-intl.md +1 -1
  70. package/docs/hi/intlayer_with_tanstack+solid.md +24 -5
  71. package/docs/hi/intlayer_with_tanstack.md +45 -68
  72. package/docs/id/bundle_optimization.md +454 -0
  73. package/docs/id/intlayer_with_next-i18next.md +1 -1
  74. package/docs/id/intlayer_with_next-intl.md +1 -1
  75. package/docs/id/intlayer_with_tanstack+solid.md +24 -5
  76. package/docs/id/intlayer_with_tanstack.md +45 -68
  77. package/docs/it/bundle_optimization.md +454 -0
  78. package/docs/it/intlayer_with_next-i18next.md +1 -1
  79. package/docs/it/intlayer_with_next-intl.md +1 -1
  80. package/docs/it/intlayer_with_tanstack+solid.md +24 -5
  81. package/docs/it/intlayer_with_tanstack.md +45 -68
  82. package/docs/ja/bundle_optimization.md +454 -0
  83. package/docs/ja/intlayer_with_next-i18next.md +1 -1
  84. package/docs/ja/intlayer_with_next-intl.md +1 -1
  85. package/docs/ja/intlayer_with_tanstack+solid.md +24 -5
  86. package/docs/ja/intlayer_with_tanstack.md +45 -36
  87. package/docs/ko/bundle_optimization.md +454 -0
  88. package/docs/ko/intlayer_with_next-i18next.md +1 -1
  89. package/docs/ko/intlayer_with_next-intl.md +1 -1
  90. package/docs/ko/intlayer_with_tanstack+solid.md +24 -5
  91. package/docs/ko/intlayer_with_tanstack.md +45 -68
  92. package/docs/nl/bundle_optimization.md +454 -0
  93. package/docs/pl/bundle_optimization.md +454 -0
  94. package/docs/pl/intlayer_with_next-i18next.md +1 -1
  95. package/docs/pl/intlayer_with_next-intl.md +1 -1
  96. package/docs/pl/intlayer_with_tanstack+solid.md +24 -5
  97. package/docs/pl/intlayer_with_tanstack.md +45 -68
  98. package/docs/pt/bundle_optimization.md +454 -0
  99. package/docs/pt/intlayer_with_next-i18next.md +1 -1
  100. package/docs/pt/intlayer_with_next-intl.md +1 -1
  101. package/docs/pt/intlayer_with_tanstack+solid.md +24 -5
  102. package/docs/pt/intlayer_with_tanstack.md +45 -68
  103. package/docs/ru/bundle_optimization.md +454 -0
  104. package/docs/ru/intlayer_with_next-i18next.md +1 -1
  105. package/docs/ru/intlayer_with_next-intl.md +1 -1
  106. package/docs/ru/intlayer_with_tanstack+solid.md +24 -5
  107. package/docs/ru/intlayer_with_tanstack.md +45 -68
  108. package/docs/tr/bundle_optimization.md +454 -0
  109. package/docs/tr/intlayer_with_next-i18next.md +1 -1
  110. package/docs/tr/intlayer_with_next-intl.md +1 -1
  111. package/docs/tr/intlayer_with_tanstack+solid.md +24 -5
  112. package/docs/tr/intlayer_with_tanstack.md +45 -68
  113. package/docs/uk/bundle_optimization.md +454 -0
  114. package/docs/uk/intlayer_with_next-i18next.md +1 -1
  115. package/docs/uk/intlayer_with_next-intl.md +1 -1
  116. package/docs/uk/intlayer_with_tanstack+solid.md +24 -5
  117. package/docs/uk/intlayer_with_tanstack.md +45 -68
  118. package/docs/ur/bundle_optimization.md +454 -0
  119. package/docs/vi/bundle_optimization.md +454 -0
  120. package/docs/vi/intlayer_with_next-i18next.md +1 -1
  121. package/docs/vi/intlayer_with_next-intl.md +1 -1
  122. package/docs/vi/intlayer_with_tanstack+solid.md +24 -5
  123. package/docs/vi/intlayer_with_tanstack.md +45 -68
  124. package/docs/zh/bundle_optimization.md +454 -0
  125. package/docs/zh/intlayer_with_next-i18next.md +1 -1
  126. package/docs/zh/intlayer_with_next-intl.md +1 -1
  127. package/docs/zh/intlayer_with_tanstack+solid.md +24 -5
  128. package/docs/zh/intlayer_with_tanstack.md +45 -68
  129. package/package.json +7 -7
@@ -239,7 +239,10 @@ bun add -d @intlayer/babel
239
239
  ```
240
240
 
241
241
  ```typescript fileName="babel.config.js"
242
- const { getOptimizePluginOptions } = require("@intlayer/babel");
242
+ const {
243
+ getOptimizePluginOptions,
244
+ intlayerOptimizeBabelPlugin,
245
+ } = require("@intlayer/babel");
243
246
 
244
247
  module.exports = {
245
248
  plugins: [[intlayerOptimizeBabelPlugin, getOptimizePluginOptions()]],
@@ -337,7 +340,9 @@ export default config;
337
340
 
338
341
  ### Import Mode
339
342
 
340
- For large applications, including several pages and locales, your JSON can represent a significant part of your bundle size. Intlayer allows you to control how dictionaries are loaded.
343
+ For large applications, including several pages and locales, your JSON can represent a significant part of your bundle size. Intlayer allows you to control how dictionaries are loaded using the `importMode` option.
344
+
345
+ ### Global definition
341
346
 
342
347
  The import mode can be defined by default globally in your `intlayer.config.ts` file.
343
348
 
@@ -345,14 +350,16 @@ The import mode can be defined by default globally in your `intlayer.config.ts`
345
350
  import type { IntlayerConfig } from "intlayer";
346
351
 
347
352
  const config: IntlayerConfig = {
348
- build: {
349
- minify: true,
353
+ dictionary: {
354
+ importMode: "dynamic", // Default is 'static'
350
355
  },
351
356
  };
352
357
 
353
358
  export default config;
354
359
  ```
355
360
 
361
+ ### Per dictionary fine-grained definition
362
+
356
363
  As well as for each dictionaries in your `.content.{{ts|tsx|js|jsx|mjs|cjs|json|jsonc|json5}}` files.
357
364
 
358
365
  ```ts
@@ -390,7 +397,8 @@ In static mode, Intlayer replaces `useIntlayer` with `useDictionary` and injects
390
397
  // Your code
391
398
  const content = useIntlayer("my-key");
392
399
 
393
- // Optimized code (Static)
400
+ // Optimized code illustration after transformation (Static)
401
+ // This is only for illustration purposes, the actual code will be different for optimization reasons
394
402
  const content = useDictionary({
395
403
  key: "my-key",
396
404
  content: {
@@ -417,7 +425,8 @@ In dynamic mode, Intlayer replaces `useIntlayer` with `useDictionaryAsync`. This
417
425
  // Your code
418
426
  const content = useIntlayer("my-key");
419
427
 
420
- // Optimized code (Dynamic)
428
+ // Optimized code illustration after transformation (Dynamic)
429
+ // This is only for illustration purposes, the actual code will be different for optimization reasons
421
430
  const content = useDictionaryAsync({
422
431
  en: () =>
423
432
  import(".intlayer/dynamic_dictionary/my-key/en.json").then(
@@ -430,12 +439,31 @@ const content = useDictionaryAsync({
430
439
  });
431
440
  ```
432
441
 
433
- > When using `importMode: 'dynamic'`, if you have 100 components using `useIntlayer` on a single page, the browser will attempt 100 separate fetches. To avoid this "waterfall" of requests, group content into fewer `.content` files (e.g., one dictionary per page section) rather than one per atom component.
442
+ > When using `importMode: 'dynamic'`, if you have 100 components using `useIntlayer` on a single page, the browser will attempt 100 separate fetches. To avoid this "waterfall" of requests, group content into fewer `.content` files (e.g., one dictionary per page section) rather than one per atom component. You can also use multiple `.content` files using the same key. Intlayer will merge them into a single dictionary.
434
443
 
435
444
  ### 3. Fetch Mode
436
445
 
437
446
  Behaves similarly to Dynamic mode but attempts to fetch dictionaries from the Intlayer Live Sync API first. If the API call fails or the content is not marked for live updates, it falls back to the dynamic import.
438
447
 
448
+ **Transformed Code Example:**
449
+
450
+ ```tsx
451
+ // Your code
452
+ const content = useIntlayer("my-key");
453
+
454
+ // Optimized code illustration (Fetch)
455
+ const content = useDictionaryAsync({
456
+ en: () =>
457
+ fetch("https://intlayer.my-domain.com/dictionary/my-key/en").then((res) =>
458
+ res.json()
459
+ ),
460
+ fr: () =>
461
+ fetch("https://intlayer.my-domain.com/dictionary/my-key/fr").then((res) =>
462
+ res.json()
463
+ ),
464
+ });
465
+ ```
466
+
439
467
  > See CMS documentation for more details: [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)
440
468
 
441
469
  > In fetch mode, purge and minification can't be used.
@@ -446,6 +474,6 @@ Behaves similarly to Dynamic mode but attempts to fetch dictionaries from the In
446
474
  | :------------------- | :-------------------------------------------- | :----------------------------------- |
447
475
  | **JS Bundle Size** | Larger (includes all langs for the component) | Smallest (only code, no content) |
448
476
  | **Initial Load** | Instant (Content is in bundle) | Slight delay (Fetches JSON) |
449
- | **Network Requests** | 0 extra requests | 1 request per dictionary |
477
+ | **Network Requests** | 0 extra requests | 1 request per dictionary key |
450
478
  | **Tree Shaking** | Component-level | Component-level + Locale-level |
451
479
  | **Best Use Case** | UI Components, Small Apps | Pages with much text, Many Languages |
@@ -256,7 +256,7 @@ export default function LocaleLayout({
256
256
  params: { locale: string };
257
257
  }) {
258
258
  const locale: Locale = (locales as readonly string[]).includes(params.locale)
259
- ? (params.locale as any)
259
+ ? params.locale
260
260
  : defaultLocale;
261
261
 
262
262
  const dir = isRtl(locale) ? "rtl" : "ltr";
@@ -103,7 +103,7 @@ async function loadMessages(locale: string) {
103
103
  }
104
104
 
105
105
  export default getRequestConfig(async ({ locale }) => {
106
- if (!locales.includes(locale as any)) notFound();
106
+ if (!locales.includes(locale)) notFound();
107
107
 
108
108
  return {
109
109
  messages: await loadMessages(locale),
@@ -197,9 +197,7 @@ const RootComponent: ParentComponent = (props) => {
197
197
  </head>
198
198
  <body>
199
199
  <IntlayerProvider locale={locale}>
200
- <Suspense>
201
- {props.children}
202
- </Suspense>
200
+ <Suspense>{props.children}</Suspense>
203
201
  </IntlayerProvider>
204
202
  <Scripts />
205
203
  </body>
@@ -509,12 +507,33 @@ export const Route = createFileRoute("/{-$locale}/")({
509
507
  component: RouteComponent,
510
508
  head: ({ params }) => {
511
509
  const { locale } = params;
512
- const metaContent = getIntlayer("page-metadata", locale);
510
+ const path = "/"; // The path for this route
511
+
512
+ const metaContent = getIntlayer("app", locale);
513
513
 
514
514
  return {
515
+ links: [
516
+ // Canonical link: Points to the current localized page
517
+ { rel: "canonical", href: getLocalizedUrl(path, locale) },
518
+
519
+ // Hreflang: Tell Google about all localized versions
520
+ ...localeMap(({ locale: mapLocale }) => ({
521
+ rel: "alternate",
522
+ hrefLang: mapLocale,
523
+ href: getLocalizedUrl(path, mapLocale),
524
+ })),
525
+
526
+ // x-default: For users in unmatched languages
527
+ // Define the default fallback locale (usually your primary language)
528
+ {
529
+ rel: "alternate",
530
+ hrefLang: "x-default",
531
+ href: getLocalizedUrl(path, defaultLocale),
532
+ },
533
+ ],
515
534
  meta: [
516
535
  { title: metaContent.title },
517
- { content: metaContent.description, name: "description" },
536
+ { name: "description", content: metaContent.meta.description },
518
537
  ],
519
538
  };
520
539
  },
@@ -228,9 +228,7 @@ function RootDocument({ children }: { children: ReactNode }) {
228
228
  <HeadContent />
229
229
  </head>
230
230
  <body>
231
- <IntlayerProvider locale={locale}>
232
- {children}
233
- </IntlayerProvider>
231
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
234
232
  <Scripts />
235
233
  </body>
236
234
  </html>
@@ -329,30 +327,20 @@ import { getPrefix } from "intlayer";
329
327
 
330
328
  export const LOCALE_ROUTE = "{-$locale}" as const;
331
329
 
332
- // Main utility
333
- export type RemoveLocaleParam<T> = T extends string
334
- ? RemoveLocaleFromString<T>
335
- : T;
330
+ export type To = StripLocalePrefix<LinkComponentProps["to"]>;
336
331
 
337
- export type To = RemoveLocaleParam<LinkComponentProps["to"]>;
338
-
339
- type CollapseDoubleSlashes<S extends string> =
340
- S extends `${infer H}//${infer T}` ? CollapseDoubleSlashes<`${H}/${T}`> : S;
332
+ export type StripLocalePrefix<T extends string | undefined> = T extends
333
+ | `/${typeof LOCALE_ROUTE}/`
334
+ | `/${typeof LOCALE_ROUTE}`
335
+ ? "/"
336
+ : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
337
+ ? `/${Rest}`
338
+ : T;
341
339
 
342
340
  type LocalizedLinkProps = {
343
341
  to?: To;
344
342
  } & Omit<LinkComponentProps, "to">;
345
343
 
346
- // Helpers
347
- type RemoveAll<
348
- S extends string,
349
- Sub extends string,
350
- > = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;
351
-
352
- type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<
353
- RemoveAll<S, typeof LOCALE_ROUTE>
354
- >;
355
-
356
344
  export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
357
345
  const { locale } = useLocale();
358
346
  const { localePrefix } = getPrefix(locale);
@@ -381,26 +369,26 @@ Then we can create a `useLocalizedNavigate` hook for programmatic navigation:
381
369
  import { useNavigate } from "@tanstack/react-router";
382
370
  import { getPrefix } from "intlayer";
383
371
  import { useLocale } from "react-intlayer";
384
- import { LOCALE_ROUTE } from "@/components/localized-link";
372
+ import type { StripLocalePrefix } from "@/components/localized-link";
385
373
  import type { FileRouteTypes } from "@/routeTree.gen";
386
374
 
387
- type StripLocalePrefix<T extends string> = T extends
388
- | `/${typeof LOCALE_ROUTE}`
389
- | `/${typeof LOCALE_ROUTE}/`
390
- ? "/"
391
- : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
392
- ? `/${Rest}`
393
- : never;
375
+ type NavigateFn = ReturnType<typeof useNavigate>;
376
+ type BaseNavigateOptions = Parameters<NavigateFn>[0];
394
377
 
395
378
  type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;
396
379
 
397
- type LocalizedNavigate = {
398
- (to: LocalizedTo): ReturnType<ReturnType<typeof useNavigate>>;
399
- (
400
- opts: { to: LocalizedTo } & Record<string, unknown>
401
- ): ReturnType<ReturnType<typeof useNavigate>>;
380
+ export type LocalizedNavigateOptions = Omit<
381
+ BaseNavigateOptions,
382
+ "to" | "params"
383
+ > & {
384
+ to: LocalizedTo;
385
+ params?: Omit<NonNullable<BaseNavigateOptions["params"]>, "locale">;
402
386
  };
403
387
 
388
+ type LocalizedNavigate = (
389
+ options: LocalizedNavigateOptions
390
+ ) => ReturnType<NavigateFn>;
391
+
404
392
  export const useLocalizedNavigate = () => {
405
393
  const navigate = useNavigate();
406
394
 
@@ -447,38 +435,6 @@ import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";
447
435
 
448
436
  export const Route = createFileRoute("/{-$locale}/")({
449
437
  component: RouteComponent,
450
- head: ({ params }) => {
451
- const { locale } = params;
452
- const path = "/"; // The path for this route
453
-
454
- const metaContent = getIntlayer("app", locale);
455
-
456
- return {
457
- links: [
458
- // Canonical link: Points to the current localized page
459
- { rel: "canonical", href: getLocalizedUrl(path, locale) },
460
-
461
- // Hreflang: Tell Google about all localized versions
462
- ...localeMap(({ locale: mapLocale }) => ({
463
- rel: "alternate",
464
- hrefLang: mapLocale,
465
- href: getLocalizedUrl(path, mapLocale),
466
- })),
467
-
468
- // x-default: For users in unmatched languages
469
- // Define the default fallback locale (usually your primary language)
470
- {
471
- rel: "alternate",
472
- hrefLang: "x-default",
473
- href: getLocalizedUrl(path, defaultLocale),
474
- },
475
- ],
476
- meta: [
477
- { title: metaContent.title },
478
- { name: "description", content: metaContent.meta.description },
479
- ],
480
- };
481
- },
482
438
  });
483
439
 
484
440
  function RouteComponent() {
@@ -633,12 +589,33 @@ export const Route = createFileRoute("/{-$locale}/")({
633
589
  component: RouteComponent,
634
590
  head: ({ params }) => {
635
591
  const { locale } = params;
636
- const metaContent = getIntlayer("page-metadata", locale);
592
+ const path = "/"; // The path for this route
593
+
594
+ const metaContent = getIntlayer("app", locale);
637
595
 
638
596
  return {
597
+ links: [
598
+ // Canonical link: Points to the current localized page
599
+ { rel: "canonical", href: getLocalizedUrl(path, locale) },
600
+
601
+ // Hreflang: Tell Google about all localized versions
602
+ ...localeMap(({ locale: mapLocale }) => ({
603
+ rel: "alternate",
604
+ hrefLang: mapLocale,
605
+ href: getLocalizedUrl(path, mapLocale),
606
+ })),
607
+
608
+ // x-default: For users in unmatched languages
609
+ // Define the default fallback locale (usually your primary language)
610
+ {
611
+ rel: "alternate",
612
+ hrefLang: "x-default",
613
+ href: getLocalizedUrl(path, defaultLocale),
614
+ },
615
+ ],
639
616
  meta: [
640
617
  { title: metaContent.title },
641
- { content: metaContent.description, name: "description" },
618
+ { name: "description", content: metaContent.meta.description },
642
619
  ],
643
620
  };
644
621
  },