Creation:2025-09-22Last update:2026-01-26

    Nowy Intlayer v8. Co nowego?

    Witamy w Intlayer v8! Wydanie to koncentruje się na poprawie doświadczenia deweloperskiego dzięki automatycznemu wykrywaniu treści, zapewnianiu komunikacji danych poprzez walidację schematów oraz na zwiększeniu kontroli nad zarządzaniem słownikami.

    www.youtube.com

    Spis treści


    Ewolucja treści bogatych: Markdown i HTML

    Intlayer v8 wprowadza znaczące ulepszenia w sposobie obsługi treści bogatych, wprowadzając węzły HTML (które nie istniały w wersji v7) i jednocząc API z węzłami Markdown (które istniały w wersji v7, ale zostały ulepszone).

    Zunifikowane API .use()

    Wprowadziliśmy metodę .use() zarówno dla węzłów Markdown, jak i HTML. Metoda ta pozwala na dostosowanie tagów HTML lub komponentów używanych podczas renderowania.

    • Podmiana komponentów: Możesz łatwo zastąpić tagi HTML lub niestandardowe komponenty własnymi komponentami frameworka (np. zastąpić <a> przez NextLink lub <CustomCmp> przez komponent React).
    • Bezpieczeństwo typów: Wszystkie funkcje dostarczające komponenty są w pełni typowane, co gwarantuje otrzymanie poprawnych propów.

    Domyślne zachowanie renderowania

    W wersji v7, jeśli nie zdefiniowano żadnego providera, węzły Markdown były renderowane jako surowe ciągi znaków, co często wymagało zewnętrznych bibliotek do ich parsowania.

    W wersji v8 Intlayer zawiera własny, wewnętrzny parser Markdown. Domyślnie węzły Markdown są teraz renderowane bezpośrednio jako HTML bez potrzeby korzystania z zewnętrznych bibliotek.

    Nowe narzędzia Renderer i Provider

    Wprowadziliśmy nowe, samodzielne funkcje renderujące i komponenty, aby dać Ci większą kontrolę poza standardowym przepływem useIntlayer.

    • Markdown: MarkdownRenderer, useMarkdownRenderer, renderMarkdown. (Uwaga: MarkdownProvider istniał w wersji v7, ale teraz integruje się z tymi nowymi narzędziami).
    • HTML: HTMLRenderer, useHTMLRenderer, renderHTML, HTMLProvider.

    Przykłady: Narzędzia do renderowania Markdown

    1. Użycie komponentu:

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer  forceBlock={true}  components={{    h1: ({ children }) => <h1 className="text-2xl">{children}</h1>  }}>  {"# Mój Tytuł"}</MarkdownRenderer>

    2. Użycie hooka:

    tsx
    import { useMarkdownRenderer } from "react-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({  components: {    h1: ({ children }) => <h1 className="text-red-500">{children}</h1>  }});return <div>{renderMarkdown("# Mój Tytuł")}</div>;

    3. Użycie funkcji narzędziowej:

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";const html = renderMarkdown("# Mój Tytuł", {  forceBlock: true});

    Przykłady: Narzędzia do renderowania HTML

    1. Użycie komponentu:

    tsx
    import { HTMLRenderer } from "react-intlayer/html";<HTMLRenderer  components={{    p: ({ children }) => <p className="mb-4">{children}</p>  }}>  {"<p>Witaj świecie</p>"}</HTMLRenderer>

    2. Użycie hooka:

    tsx
    import { useHTMLRenderer } from "react-intlayer/html";const renderHTML = useHTMLRenderer({  components: {    strong: ({ children }) => <b className="font-bold">{children}</b>  }});return <div>{renderHTML("<p>Witaj <strong>świecie</strong></p>")}</div>;

    3. Użycie funkcji narzędziowej:

    tsx
    import { renderHTML } from "react-intlayer/html";const html = renderHTML("<p>Witaj świecie</p>");

    Więcej informacji znajdziesz w Dokumentacji treści HTML oraz Dokumentacji Markdown.


    Niestandardowe przepisywanie URL

    Intlayer v8 wprowadza obsługę niestandardowego przepisywania URL, co pozwala definiować ścieżki specyficzne dla lokalizacji, różne od standardowej struktury /locale/path. To potężna funkcja poprawiająca lokalne SEO i zapewniająca bardziej naturalne doświadczenie użytkownika dla osób nieposługujących się angielskim.

    Kluczowe ulepszenia w wersji 8:

    • Formatery dla frameworków: Nowe nextjsRewrite, svelteKitRewrite, reactRouterRewrite, vueRouterRewrite, solidRouterRewrite, tanstackRouterRewrite, nuxtRewrite oraz viteRewrite, które zapewniają idiomatyczną składnię wzorców dla każdego routera.
    • Hook useRewriteURL: Nowy hook po stronie klienta, który dyskretnie koryguje pasek adresu do „ładnego” zlokalizowanego URL-a bez wywoływania nawigacji routera.
    • Automatyczne przekierowania SEO: Wbudowane proxy teraz automatycznie przekierowują użytkowników z ręcznie wpisanych kanonicznych ścieżek (np. /fr/about) do ich ładniejszych zlokalizowanych wersji (np. /fr/a-propos).

    Przykładowa konfiguracja:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";import { nextjsRewrite } from "intlayer/routing";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  routing: {    mode: "prefix-no-default",    rewrite: nextjsRewrite({      "/[locale]/about": {        fr: "/[locale]/a-propos",        es: "/[locale]/acerca-de",      },      "/[locale]/products/[id]": {        fr: "/[locale]/produits/[id]",        es: "/[locale]/productos/[id]",      },    }),  },};export default config;

    Ta funkcja jest obsługiwana domyślnie w Next.js i Vite przez proxy Intlayer i może być łatwo zintegrowana z innymi routerami, takimi jak TanStack Router, React Router, Vue Router, SvelteKit i Solid Router.

    Po więcej informacji i przewodników integracyjnych zobacz Dokumentację niestandardowych przekierowań URL.


    Ulepszone wartości wstawień

    W v8 wartości wstawień mogą teraz przyjmować elementy React (lub węzły Vue) oprócz stringów i liczb. Pozwala to na wstrzykiwanie bogatych, interaktywnych komponentów bezpośrednio do Twoich szablonów wstawień.

    Intlayer teraz solidnie obsługuje zagnieżdżone węzły React i Preact w wstawieniach, zapewniając zachowanie i poprawne renderowanie złożonych struktur interfejsu użytkownika.

    Przykład:

    src/example.content.ts
    import { insert } from "intlayer";export default {  key: "my-key",  content: {    myInsertion: insert("Witaj {{name}}"),  },};
    tsx
    import { useIntlayer } from "next-intlayer";const { myInsertion } = useIntlayer("my-key");return (  <div>    {myInsertion({      name: 2, // liczba      // lub      name: "John", // tekst      // lub      name: <span>John</span>, // element React    })}  </div>);

    Walidacja schematów treści

    W Intlayer v8 wprowadzono walidację schematów dla słowników. Teraz możesz definiować wielokrotnego użytku schematy walidacji w konfiguracji przy użyciu Zod i stosować je w plikach z zawartością. Dzięki temu Twoja zawartość zawsze będzie zgodna z oczekiwaną strukturą, a błędy zostaną wykryte podczas budowania (build time).

    1. Zdefiniuj schematy

    Zdefiniuj swoje schematy w intlayer.config.ts:

    intlayer.config.ts
    import { z } from "zod";export default {  schemas: {    "seo-metadata": z.object({      title: z.string().min(50).max(60),      description: z.string().min(150).max(160),    }),  },};

    2. Zastosuj schematy do słowników

    Odwołaj się do klucza schematu w definicji słownika:

    src/example.content.ts
    import { type Dictionary } from "intlayer";const aboutPageMetaContent = {  key: "about-page-meta",  schema: "seo-metadata", // <-- klucz schematu  content: {    title: "O naszej firmie, dowiedz się więcej",    description: "Poznaj misję, wartości i zespół naszej firmy.",  },} satisfies Dictionary;export default aboutPageMetaContent;

    Jeżeli zawartość nie spełnia schematu (np. tytuł jest zbyt krótki), proces budowania zgłosi błąd.


    Ulepszone automatyczne wykrywanie zawartości

    W wersji v8 Intlayer inteligentnie wykrywa składnię Markdown, tagi HTML oraz wstawienia zmiennych w ciągach treści. Oznacza to, że często możesz pominąć pomocnicze funkcje takie jak md(), html() czy insert().

    To zachowanie jest włączone domyślnie. Możesz teraz dopracować to wykrywanie globalnie w pliku intlayer.config.ts lub dla poszczególnego słownika.

    Kontrola szczegółowa

    Możesz włączać lub wyłączać konkretne typy transformacji:

    intlayer.config.ts
    export default {  dictionary: {    // contentAutoTransformation: false (domyślnie)    contentAutoTransformation: {      markdown: true,      html: true,      insertion: false, // Wyłącz automatyczne wykrywanie wstawek    },  },};

    Zachowanie v7 (Ręczne opakowywanie):

    src/example.content.ts
    import { md, insert } from "intlayer";export default {  key: "my-key",  content: {    myMarkdown: md("## Hello World"),    myInsertion: insert("Witaj {{name}}"),  },};

    Zachowanie v8 (Automatyczne wykrywanie):

    src/example.content.ts
    export default {  key: "my-key",  contentAutoTransformation: true, // Można też ustawić w definicji słownika lub globalnie w intlayer.config.ts  content: {    myMarkdown: "## Hello World", // Automatycznie rozpoznane jako Markdown    myHTML: "<p>Hello World</p>", // Automatycznie rozpoznane jako HTML    myInsertion: "Witaj {{name}}", // Automatycznie rozpoznane jako Insertion  },};

    Podstawowy wynik JSON pozostaje niezmieniony, zachowując szczegółowe informacje o typach potrzebne do renderowania:

    json
    {  "key": "my-key",  "content": {    "myMarkdown": {      "nodeType": "markdown",      "markdown": "## Hello World"    },    "myHTML": {      "nodeType": "html",      "html": "<p>Hello World</p>"    },    "myInsertion": {      "nodeType": "insertion",      "insertion": "Hi {{name}}"    }  }}

    Lokalizacja: nowy hook useIntl

    Nowy hook useIntl() jest teraz dostępny w React, Next.js i Vue. Zapewnia obiekt Intl powiązany z locale, który automatycznie używa bieżącego języka do formatowania liczb, dat i innych, bez potrzeby ręcznego przekazywania locale.

    tsx
    import { useIntl } from "next-intlayer";const intl = useIntl();const formattedPrice = new intl.NumberFormat({  style: "currency",  currency: "USD",}).format(123.45);

    Narzędzia: Ulepszenia rozszerzenia VSCode

    Rozszerzenie Intlayer dla VSCode otrzymuje znaczące aktualizacje w wersji v8, aby usprawnić proces internacjonalizacji:

    • Czas uruchamiania: Poprawa wydajności podczas otwierania projektu.
    • Buforowanie: Ulepszona warstwa buforowania zapewniająca niemal natychmiastową walidację i autouzupełnianie.
    • Wykrywanie nieużywanych i zduplikowanych kluczy: Nowe funkcje automatycznie wykrywające nieużywane klucze i zduplikowane klucze w Twoich słownikach, pomagając utrzymać zawartość czystą i wydajną.

    Optymalizacje kompilatora

    Intlayer v8 zawiera nową warstwę cache'owania dla kompilatora Markdown i HTML. Zapewnia to, że identyczne ciągi treści z tą samą konfiguracją są parsowane tylko raz, co znacząco zmniejsza narzut podczas ponownych renderów lub przy użyciu tej samej treści w wielu miejscach.

    babel.config.js
      const {  intlayerExtractBabelPlugin,  intlayerOptimizeBabelPlugin,  getExtractPluginOptions,  getOptimizePluginOptions,} = require('@intlayer/babel');module.exports = {  presets: ['next/babel'],  plugins: [    // Wyodrębnij zawartość z komponentów do słowników    [intlayerExtractBabelPlugin, getExtractPluginOptions()],    // Optymalizuj importy, zastępując useIntlayer bezpośrednimi importami słowników    [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],  ],};

    Elastyczność: Ujednolicony tryb importu

    Właściwość boolean live została oznaczona jako przestarzała na rzecz bardziej wszechstronnej właściwości importMode. Pozwala to na jednoznaczne określenie, w jaki sposób słowniki powinny być ładowane: statycznie, dynamicznie lub poprzez synchronizację w czasie rzeczywistym.

    Tryby

    • static (Domyślny): Słownik jest dołączany podczas budowania (build time). Najlepsze dla wydajności.
    • dynamic: Słownik jest ładowany w czasie wykonywania (np. przez pobranie JSON lub użycie Suspense).
    • fetch: Słownik jest pobierany z CMS/serwera w czasie wykonywania i synchronizowany.

    Migracja:

    v7 Konfiguracja v8 Konfiguracja
    live: true importMode: 'fetch'
    live: false importMode: 'static' (lub 'dynamic')

    Uwaga: W Intlayer v8 właściwość importMode została przeniesiona z konfiguracji build do konfiguracji dictionary w pliku intlayer.config.ts. Pozwala to zdefiniować domyślny tryb importu dla wszystkich słowników, jednocześnie umożliwiając nadpisanie go dla poszczególnych słowników.

    Przykład konfiguracji globalnej:

    intlayer.config.ts
    export default {  dictionary: {    importMode: "dynamic", // Domyślne ustawienie globalne  },  // ...};

    Przykład słownika:

    src/example.content.ts
    export default {    key: 'my-key',    importMode: "fetch", // Nadpisuje konfigurację globalną    content: { ... }}

    Kontrola lokalizacji słowników

    W wersji v8 wprowadzono właściwość location, która pozwala jawnie określić, gdzie znajdują się słowniki i jak są synchronizowane. Jest to szczególnie przydatne w hybrydowych przepływach pracy łączących pliki lokalne ze zdalną zawartością CMS.

    Opcje

    • local: Słownik istnieje tylko lokalnie. Nie zostanie wysłany do zdalnego CMS.
    • remote: Słownik jest zarządzany zdalnie. Po wypchnięciu na CMS zostanie odłączony od lokalnego. Zdalny słownik będzie pobierany z CMS.
    • local_and_remote: Słownik istnieje w obu miejscach. Lokalne zmiany są wypychane, a zdalne zmiany są pobierane (synchronizowane).

    Przykład:

    src/example.content.ts
    export default {    key: 'my-key',    location: "local", // Zachowaj ten słownik tylko lokalnie    content: { ... }}

    Oddzielenie konfiguracji systemu

    Intlayer v8 oddziela konfigurację źródeł treści od wewnętrznych ścieżek systemowych i wyjściowych. To oczyszcza właściwość content i jasno wskazuje, które ustawienia są przeznaczone do zarządzania przez użytkownika, a które są zarządzane przez system Intlayer.

    Następujące właściwości zostały przeniesione z content do nowej właściwości system w intlayer.config.ts:

    • dictionariesDir
    • moduleAugmentationDir
    • unmergedDictionariesDir
    • typesDir
    • mainDir
    • configDir
    • cacheDir
    • outputFilesPatternWithPath

    Zachowanie w v7:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src"],    dictionariesDir: ".intlayer/dictionary", // Mieszane z konfiguracją źródła  },};

    Zachowanie w v8:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src"],  },  system: {    dictionariesDir: ".intlayer/dictionary", // Wyraźne rozdzielenie  },};

    Oddzielenie katalogów treści i kodu

    Intlayer v8 oddziela konfigurację plików definiujących treść od konfiguracji transformacji kodu. Pozwala to na dokładniejsze obserwowanie i skanowanie, poprawiając wydajność budowania.

    Wcześniej contentDir było używane zarówno do obserwowania plików .content.*, jak i do skanowania kodu pod kątem wywołań useIntlayer. Teraz:

    • contentDir: Konkretnie dla plików definiujących treść.
    • codeDir: Konkretnie dla kodu aplikacji, który wymaga transformacji (np. pruning, optymalizacja).

    Migracja:

    Jeśli wcześniej ustawiłeś contentDir, Intlayer v8 użyje go również jako domyślnego dla codeDir, ale zaloguje ostrzeżenie. Powinieneś jawnie zdefiniować codeDir w swojej konfiguracji.

    Zachowanie w v7:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src", "@packages/design-system"], // Używane zarówno dla zawartości, jak i kodu  },};

    Zachowanie w v8:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src/content", "@packages/design-system"], // Tylko obserwuj tutaj pliki src/content/*.content.* oraz pliki @packages/design-system/dist/*.content.*    codeDir: ["src", "@packages/design-system"], // Tylko skanuj w tym miejscu w celu transformacji kodu oraz pliki @packages/design-system/src/*.content.*  },};

    Framework: Ulepszenia Svelte

    Treści Markdown i HTML w Svelte są teraz automatycznie parsowane do HTML podczas serializacji. Ułatwia to użycie składni Svelte {@html}, ponieważ teraz można po prostu przekazać bezpośrednio węzeł zawartości.


    Notatki migracyjne z v7

    Zmiany w konfiguracji

    • Właściwość live: Właściwość live w słownikach została usunięta. Zamiast niej użyj importMode: 'fetch'.
    • importMode: Właściwość build.importMode w konfiguracji jest przestarzała. Zamiast niej użyj dictionary.importMode.
    • contentDir i codeDir: contentDir jest teraz przeznaczony wyłącznie dla plików z treścią. Dodano nowe pole codeDir do transformacji kodu. Jeśli codeDir nie zostanie ustawione, Intlayer użyje contentDir jako fallback i zaloguje ostrzeżenie.
    • Walidacja schematu: Aby użyć nowej funkcji schema, upewnij się, że masz zainstalowany pakiet zod w swoim projekcie.

    Przydatne linki