---
createdAt: 2025-09-22
updatedAt: 2026-01-26
title: Nowy Intlayer v8. Co nowego?
description: Odkryj, co nowego w Intlayer v8. Znaczące ulepszenia w doświadczeniu deweloperskim, walidacji treści i zarządzaniu słownikami.
keywords:
  - Intlayer
  - CMS
  - Doświadczenie dewelopera
  - Funkcje
  - React
  - Next.js
  - JavaScript
  - TypeScript
youtubeVideo: https://www.youtube.com/watch?v=ia6JmVf-kkU
slugs:
  - doc
  - releases
  - v8
---

# 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.

<iframe
  src="https://www.youtube.com/embed/ia6JmVf-kkU"
  className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
  title="Demo Video - New Intlayer v8 - What's new?"
  sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
  loading="lazy"
/>

## Spis treści

<TOC levels={[2]} maxDepth={1} />

---

## 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

<Tabs group='framework'>
  <Tab label="React / Next.js" value="react">

    **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
    });
    ```

  </Tab>
  <Tab label="Vue" value="vue">

    **1. Użycie komponentu:**

    ```vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>

    <template>
      <MarkdownRenderer :forceBlock="true" content="# Mój Tytuł" />
    </template>
    ```

  </Tab>
  <Tab label="Svelte" value="svelte">

    **1. Użycie komponentu:**

    ```svelte
    <script>
      import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>

    <MarkdownRenderer forceBlock={true} value="# Mój Tytuł" />
    ```

    **2. Użycie hooka:**

    ```svelte
    <script>
      import { useMarkdownRenderer } from "svelte-intlayer/markdown";
      const render = useMarkdownRenderer();
    </script>

    {@html render("# Mój Tytuł")}
    ```

    **3. Użycie funkcji narzędziowej:**

    ```svelte
    <script>
      import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>

    {@html renderMarkdown("# Mój Tytuł")}
    ```

  </Tab>
  <Tab label="Angular" value="angular">

    **1. Użycie usługi:**

    ```typescript
    import { Component } from "@angular/core";
    import { IntlayerMarkdownService } from "angular-intlayer";

    @Component({ ... })
    export class MyComponent {
      constructor(private markdownService: IntlayerMarkdownService) {}

      render(markdown: string) {
        return this.markdownService.renderMarkdown(markdown);
      }
    }
    ```

  </Tab>
  <Tab label="Solid" value="solid">

    **1. Użycie komponentu:**

    ```tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";

    <MarkdownRenderer forceBlock={true}>
      {"# Mój Tytuł"}
    </MarkdownRenderer>
    ```

    **2. Użycie hooka:**

    ```tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";

    const render = useMarkdownRenderer();

    return <div>{render("# Mój Tytuł")}</div>;
    ```

    **3. Użycie funkcji narzędziowej:**

    ```tsx
    import { renderMarkdown } from "solid-intlayer/markdown";

    return <div>{renderMarkdown("# Mój Tytuł")}</div>;
    ```

  </Tab>
  <Tab label="Preact" value="preact">

    **1. Użycie komponentu:**

    ```tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";

    <MarkdownRenderer forceBlock={true}>
      {"# Mój Tytuł"}
    </MarkdownRenderer>
    ```

    **2. Użycie hooka:**

    ```tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";

    const render = useMarkdownRenderer();

    return <div>{render("# Mój Tytuł")}</div>;
    ```

    **3. Użycie funkcji narzędziowej:**

    ```tsx
    import { renderMarkdown } from "preact-intlayer/markdown";

    return <div>{renderMarkdown("# Mój Tytuł")}</div>;
    ```

  </Tab>
</Tabs>

#### Przykłady: Narzędzia do renderowania HTML

<Tabs group='framework'>
  <Tab label="React / Next.js" value="react">

    **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>");
    ```

  </Tab>
  <Tab label="Vue" value="vue">

    **1. Użycie komponentu:**

    ```vue
    <script setup>
    import { HTMLRenderer } from "vue-intlayer/html";
    </script>

    <template>
      <HTMLRenderer content="<p>Witaj świecie</p>" />
    </template>
    ```

  </Tab>
  <Tab label="Svelte" value="svelte">

    **1. Użycie komponentu:**

    ```svelte
    <script>
      import { HTMLRenderer } from "svelte-intlayer/html";
    </script>

    <HTMLRenderer value="<p>Witaj świecie</p>" />
    ```

    **2. Użycie hooka:**

    ```svelte
    <script>
      import { useHTMLRenderer } from "svelte-intlayer/html";
      const render = useHTMLRenderer();
    </script>

    {@html render("<p>Witaj świecie</p>")}
    ```

    **3. Użycie funkcji narzędziowej:**

    ```svelte
    <script>
      import { renderHTML } from "svelte-intlayer/html";
    </script>

    {@html renderHTML("<p>Witaj świecie</p>")}
    ```

  </Tab>
  <Tab label="Angular" value="angular">

    **1. Bezpośrednie użycie:**

    W Angularze możesz użyć standardowego powiązania `[innerHTML]`.

    ```html
    <div [innerHTML]="'<p>Witaj świecie</p>'"></div>
    ```

  </Tab>
  <Tab label="Solid" value="solid">

    **1. Użycie komponentu:**

    ```tsx
    import { HTMLRenderer } from "solid-intlayer/html";

    <HTMLRenderer>
      {"<p>Witaj świecie</p>"}
    </HTMLRenderer>
    ```

    **2. Użycie hooka:**

    ```tsx
    import { useHTMLRenderer } from "solid-intlayer/html";

    const render = useHTMLRenderer();

    return <div>{render("<p>Witaj świecie</p>")}</div>;
    ```

    **3. Użycie funkcji narzędziowej:**

    ```tsx
    import { renderHTML } from "solid-intlayer/html";

    return <div>{renderHTML("<p>Witaj świecie</p>")}</div>;
    ```

  </Tab>
  <Tab label="Preact" value="preact">

    **1. Użycie komponentu:**

    ```tsx
    import { HTMLRenderer } from "preact-intlayer/html";

    <HTMLRenderer>
      {"<p>Witaj świecie</p>"}
    </HTMLRenderer>
    ```

    **2. Użycie hooka:**

    ```tsx
    import { useHTMLRenderer } from "preact-intlayer/html";

    const render = useHTMLRenderer();

    return <div>{render("<p>Witaj świecie</p>")}</div>;
    ```

    **3. Użycie funkcji narzędziowej:**

    ```tsx
    import { renderHTML } from "preact-intlayer/html";

    return <div>{renderHTML("<p>Witaj świecie</p>")}</div>;
    ```

  </Tab>
</Tabs>

Więcej informacji znajdziesz w [Dokumentacji treści HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/html.md) oraz [Dokumentacji Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/markdown.md).

---

## 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:**

<Tabs group='routers'>
  <Tab label="Next.js" value="nextjs">

    ```typescript fileName="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;
    ```

  </Tab>
    <Tab label="React Router" value="reactrouter">

    ```typescript fileName="intlayer.config.ts"
    import { Locales, type IntlayerConfig } from "intlayer";
    import { reactRouterRewrite } from "intlayer/routing";

    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-all",
        rewrite: reactRouterRewrite({
          "/:locale/about": {
            fr: "/:locale/a-propos",
            es: "/:locale/acerca-de",
          },
          "/:locale/products/:id": {
            fr: "/:locale/produits/:id",
            es: "/:locale/productos/:id",
          },
        }),
      },
    };

    export default config;
    ```

  </Tab>
  <Tab label="Vite (Vue, Solid, Svelte)" value="vite">

    ```typescript fileName="intlayer.config.ts"
    import { Locales, type IntlayerConfig } from "intlayer";
    import { viteRewrite } from "intlayer/routing";

    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-all",
        rewrite: viteRewrite({
          "/:locale/about": {
            fr: "/:locale/a-propos",
            es: "/:locale/acerca-de",
          },
          "/:locale/products/:id": {
            fr: "/:locale/produits/:id",
            es: "/:locale/productos/:id",
          },
        }),
      },
    };

    export default config;
    ```

  </Tab>
  <Tab label="Nuxt" value="nuxt">

    ```typescript fileName="intlayer.config.ts"
    import { Locales, type IntlayerConfig } from "intlayer";
    import { nuxtRewrite } from "intlayer/routing";

    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-all",
        rewrite: nuxtRewrite({
          "/[locale]/about": {
            fr: "/[locale]/a-propos",
            es: "/[locale]/acerca-de",
          },
          "/[locale]/products/[id]": {
            fr: "/[locale]/produits/[id]",
            es: "/[locale]/productos/[id]",
          },
        }),
      },
    };

    export default config;
    ```

  </Tab>
  <Tab label="SvelteKit" value="sveltekit">

    ```typescript fileName="intlayer.config.ts"
    import { Locales, type IntlayerConfig } from "intlayer";
    import { svelteKitRewrite } from "intlayer/routing";

    const config: IntlayerConfig = {
      internationalization: {
        locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-all",
        rewrite: svelteKitRewrite({
          "/[locale]/about": {
            fr: "/[locale]/a-propos",
            es: "/[locale]/acerca-de",
          },
          "/[locale]/products/[id]": {
            fr: "/[locale]/produits/[id]",
            es: "/[locale]/productos/[id]",
          },
        }),
      },
    };

    export default config;
    ```

  </Tab>
</Tabs>

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](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/custom_url_rewrites.md).

---

### 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:**

```typescript fileName="src/example.content.ts"
import { insert } from "intlayer";

export default {
  key: "my-key",
  content: {
    myInsertion: insert("Witaj {{name}}"),
  },
};
```

<Tabs group='framework'>
  <Tab label="Next.js" value="nextjs">

    ```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>
    );
    ```

  </Tab>
  <Tab label="React" value="react">

    ```tsx
    import { useIntlayer } from "react-intlayer";

    const { myInsertion } = useIntlayer("my-key");

    return (
      <div>
        {myInsertion({
          name: 2, // liczba
          // lub
          name: "John", // string
          // lub
          name: <span>John</span>, // element React
        })}
      </div>
    );
    ```

  </Tab>
  <Tab label="Vue" value="vue">

    ```vue
    <script setup>
    import { h } from "vue";
    import { useIntlayer } from "vue-intlayer";

    const { myInsertion } = useIntlayer("my-key");
    </script>

    <template>
      <div>
        <component
          :is="myInsertion({
            name: 2,
            // lub
            name: 'John',
            // lub
            name: h('span', 'John'),
          })"
        />
      </div>
    </template>
    ```

  </Tab>
  <Tab label="Preact" value="preact">

    ```tsx
    import { useIntlayer } from "preact-intlayer";

    const { myInsertion } = useIntlayer("my-key");

    return (
      <div>
        {myInsertion({
          name: 2, // liczba
          // lub
          name: "John", // ciąg znaków
          // lub
          name: <span>John</span>, // element Preact
        })}
      </div>
    );
    ```

  </Tab>
  <Tab label="Solid" value="solid">

    ```tsx
    import { useIntlayer } from "solid-intlayer";

    const { myInsertion } = useIntlayer("my-key");

    return (
      <div>
        {myInsertion({
          name: 2, // liczba
          // lub
          name: "John", // ciąg znaków
          // lub
          name: <span>John</span>, // element Solid
        })}
      </div>
    );
    ```

  </Tab>
  <Tab label="Svelte" value="svelte">

    ```svelte
    <script>
      import { useIntlayer } from "svelte-intlayer";

      const { myInsertion } = useIntlayer("my-key");
    </script>

    <div>
      {myInsertion({
        name: 2, // liczba
        // lub
        name: "John", // łańcuch znaków
      })}
    </div>
    ```

  </Tab>
  <Tab label="Angular" value="angular">

    ```typescript
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";

    @Component({
      selector: "app-insertion-example",
      template: `
        <div>
          {{ content().myInsertion({
            name: 'John'
          }) }}
        </div>
      `,
    })
    export class InsertionExampleComponent {
      content = useIntlayer("my-key");
    }
    ```

  </Tab>
</Tabs>

## 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.

### 1. Zdefiniuj schematy

Zdefiniuj swoje schematy w `intlayer.config.ts`:

```typescript fileName="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:

```typescript fileName="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:

```typescript fileName="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):**

```typescript fileName="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):**

```typescript fileName="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.

<Tabs group='framework'>
  <Tab label="Next.js" value="nextjs">

    ```tsx
    import { useIntl } from "next-intlayer";

    const intl = useIntl();

    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    ```

  </Tab>
  <Tab label="React" value="react">

    ```tsx
    import { useIntl } from "react-intlayer";

    const intl = useIntl();

    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    ```

  </Tab>
  <Tab label="Vue" value="vue">

    ```vue
    <script setup>
    import { useIntl } from "vue-intlayer";

    const intl = useIntl();

    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    </script>
    ```

  </Tab>
  <Tab label="Preact" value="preact">

    ```tsx
    import { useIntl } from "preact-intlayer";

    const intl = useIntl();

    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    ```

  </Tab>
  <Tab label="Solid" value="solid">

    ```tsx
    import { useIntl } from "solid-intlayer";

    const intl = useIntl();

    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    ```

  </Tab>
  <Tab label="Svelte" value="svelte">

    ```svelte
    <script>
      import { useIntl } from "svelte-intlayer";

      const intl = useIntl();

      const formattedPrice = new intl.NumberFormat({
        style: "currency",
        currency: "USD",
      }).format(123.45);
    </script>
    ```

  </Tab>
  <Tab label="Angular" value="angular">

    ```typescript
    import { Component, computed } from "@angular/core";
    import { useIntl } from "angular-intlayer";

    @Component({
      selector: "app-intl-example",
      template: `<div>{{ formattedPrice() }}</div>`,
    })
    export class IntlExampleComponent {
      intl = useIntl();

      formattedPrice = computed(() =>
        new (this.intl().NumberFormat)({
          style: "currency",
          currency: "USD",
        }).format(123.45)
      );
    }
    ```

  </Tab>
</Tabs>

---

## 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.

<Tabs group='bundler'>
  <Tab label="Next.js" value="nextjs">
  
    ```typescript fileName="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()],
      ],
    };
    ```

  </Tab>
  <Tab label="Vite" value="vite">
   
    ```typescript fileName="vite.config.js"
    import { defineConfig } from 'vite';
    import { intlayer, intlayerCompiler } from "vite-intlayer";

    export default defineConfig({
      plugins: [intlayer(), intlayerCompiler()],
    });
    ```

> Dla Vue / Svelte będziesz musiał zainstalować odpowiedni pakiet kompilatora:
>
> ```bash
> # Dla Vue
> npm install @intlayer/vue-compiler
> ```
>
> ```bash
> # Dla Svelte
> npm install @intlayer/svelte-compiler
> ```

  </Tab>
</Tabs>

---

## 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. 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:**

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

**Przykład słownika:**

```typescript fileName="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:**

```typescript fileName="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:**

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

**Zachowanie w v8:**

```typescript fileName="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:**

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

**Zachowanie w v8:**

```typescript fileName="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

- [Referencja konfiguracji](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md)
- [Dokumentacja plików treści](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md)
- [Dokumentacja treści HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/html.md)
- [Dokumentacja zawartości Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/markdown.md)
- [Dokumentacja niestandardowych przekierowań URL](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/custom_url_rewrites.md)
