---
createdAt: 2025-09-22
updatedAt: 2026-01-26
title: Nouveau Intlayer v8 - Quoi de neuf ?
description: Découvrez les nouveautés d'Intlayer v8. Améliorations majeures de l'expérience développeur, de la validation du contenu et de la gestion des dictionnaires.
keywords:
  - Intlayer
  - CMS
  - Expérience Développeur
  - Fonctionnalités
  - React
  - Next.js
  - JavaScript
  - TypeScript
youtubeVideo: https://www.youtube.com/watch?v=ia6JmVf-kkU
slugs:
  - doc
  - releases
  - v8
---

# Nouveau Intlayer v8 - Quoi de neuf ?

Bienvenue dans Intlayer v8 ! Cette version se concentre sur l'amélioration de l'expérience développeur avec la détection automatique du contenu, la garantie de l'intégrité des données avec la validation de schéma, et un meilleur contrôle sur la gestion des dictionnaires.

<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"
/>

## Table des matières

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

---

## Évolution du Contenu Riche : Markdown & HTML

Intlayer v8 apporte des améliorations majeures à la gestion du contenu riche, en introduisant les **nœuds HTML** (qui n'existaient pas en v7) et en unifiant l'API avec les **nœuds Markdown** (qui existaient en v7 mais ont été améliorés).

### L'API Unifiée `.use()`

Nous avons introduit la méthode `.use()` pour les nœuds Markdown et HTML. Cette méthode vous permet de personnaliser les balises HTML ou les composants utilisés lors du rendu.

- **Remplacement de Composants** : Vous pouvez facilement remplacer les balises HTML ou les composants personnalisés par vos propres composants de framework (par exemple, remplacer `<a>` par `NextLink` ou `<CustomCmp>` par un composant React).
- **Sécurité du Typage** : Toutes les fonctions de fourniture de composants sont entièrement typées, garantissant que vous recevez les bonnes props.

### Comportement de Rendu par Défaut

En v7, si aucun fournisseur n'était défini, les nœuds Markdown étaient rendus sous forme de chaînes de caractères brutes, nécessitant souvent des bibliothèques externes pour les analyser.

**En v8, Intlayer inclut son propre analyseur Markdown interne.** Par défaut, les nœuds Markdown sont désormais rendus directement en HTML sans avoir besoin de bibliothèques externes.

### Nouveaux Utilitaires de Rendu & de Fournisseur

Nous avons introduit de nouvelles fonctions et composants de rendu autonomes pour vous donner plus de contrôle en dehors du flux standard `useIntlayer`.

- **Markdown** : `MarkdownRenderer`, `useMarkdownRenderer`, `renderMarkdown`. (Note : `MarkdownProvider` existait en v7 mais s'intègre désormais avec ces nouveaux outils).
- **HTML** : `HTMLRenderer`, `useHTMLRenderer`, `renderHTML`, `HTMLProvider`.

#### Exemples : Outils de Rendu Markdown

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

    **1. Utilisation du Composant :**

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

    <MarkdownRenderer
      forceBlock={true}
      components={{
        h1: ({ children }) => <h1 className="text-2xl">{children}</h1>
      }}
    >
      {"# My Title"}
    </MarkdownRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const renderMarkdown = useMarkdownRenderer({
      components: {
        h1: ({ children }) => <h1 className="text-red-500">{children}</h1>
      }
    });

    return <div>{renderMarkdown("# My Title")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    const html = renderMarkdown("# My Title", {
      forceBlock: true
    });
    ```

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

    **1. Utilisation du Composant :**

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

    <template>
      <MarkdownRenderer :forceBlock="true" content="# My Title" />
    </template>
    ```

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

    **1. Utilisation du Composant :**

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

    <MarkdownRenderer forceBlock={true} value="# My Title" />
    ```

    **2. Utilisation du Hook :**

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

    {@html render("# My Title")}
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    {@html renderMarkdown("# My Title")}
    ```

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

    **1. Utilisation du Service :**

    ```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. Utilisation du Composant :**

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

    <MarkdownRenderer forceBlock={true}>
      {"# My Title"}
    </MarkdownRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const render = useMarkdownRenderer();

    return <div>{render("# My Title")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    return <div>{renderMarkdown("# My Title")}</div>;
    ```

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

    **1. Utilisation du Composant :**

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

    <MarkdownRenderer forceBlock={true}>
      {"# My Title"}
    </MarkdownRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const render = useMarkdownRenderer();

    return <div>{render("# My Title")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    return <div>{renderMarkdown("# My Title")}</div>;
    ```

  </Tab>
</Tabs>

#### Exemples : Outils de Rendu HTML

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

    **1. Utilisation du Composant :**

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

    <HTMLRenderer
      components={{
        p: ({ children }) => <p className="mb-4">{children}</p>
      }}
    >
      {"<p>Hello World</p>"}
    </HTMLRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const renderHTML = useHTMLRenderer({
      components: {
        strong: ({ children }) => <b className="font-bold">{children}</b>
      }
    });

    return <div>{renderHTML("<p>Hello <strong>World</strong></p>")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    const html = renderHTML("<p>Hello World</p>");
    ```

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

    **1. Utilisation du Composant :**

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

    <template>
      <HTMLRenderer content="<p>Hello World</p>" />
    </template>
    ```

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

    **1. Utilisation du Composant :**

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

    <HTMLRenderer value="<p>Hello World</p>" />
    ```

    **2. Utilisation du Hook :**

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

    {@html render("<p>Hello World</p>")}
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    {@html renderHTML("<p>Hello World</p>")}
    ```

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

    **1. Utilisation Directe :**

    En Angular, vous pouvez utiliser la liaison standard `[innerHTML]`.

    ```html
    <div [innerHTML]="'<p>Hello World</p>'"></div>
    ```

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

    **1. Utilisation du Composant :**

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

    <HTMLRenderer>
      {"<p>Hello World</p>"}
    </HTMLRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const render = useHTMLRenderer();

    return <div>{render("<p>Hello World</p>")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    return <div>{renderHTML("<p>Hello World</p>")}</div>;
    ```

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

    **1. Utilisation du Composant :**

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

    <HTMLRenderer>
      {"<p>Hello World</p>"}
    </HTMLRenderer>
    ```

    **2. Utilisation du Hook :**

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

    const render = useHTMLRenderer();

    return <div>{render("<p>Hello World</p>")}</div>;
    ```

    **3. Utilisation de la Fonction Utilitaire :**

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

    return <div>{renderHTML("<p>Hello World</p>")}</div>;
    ```

  </Tab>
</Tabs>

Pour plus de détails, consultez la [Documentation sur le Contenu HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/html.md) et la [Documentation sur le Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/markdown.md).

---

## Réécritures d'URL Personnalisées

Intlayer v8 introduit la prise en charge des **réécritures d'URL personnalisées**, vous permettant de définir des chemins spécifiques à la langue qui diffèrent de la structure standard `/locale/path`. C'est une fonctionnalité puissante pour améliorer le SEO local et offrir une expérience utilisateur plus naturelle aux non-anglophones.

**Principales améliorations en v8 :**

- **Formatteurs de Framework** : Nouveaux `nextjsRewrite`, `svelteKitRewrite`, `reactRouterRewrite`, `vueRouterRewrite`, `solidRouterRewrite`, `tanstackRouterRewrite`, `nuxtRewrite` et `viteRewrite` pour fournir une syntaxe de motif idiomatique pour chaque routeur.
- **Hook `useRewriteURL`** : Un nouveau hook côté client qui corrige silencieusement la barre d'adresse vers l'URL localisée "esthétique" sans déclencher de navigation de routeur.
- **Redirections SEO Automatiques** : Les proxys intégrés redirigent désormais automatiquement les utilisateurs des chemins canoniques saisis manuellement (par exemple, `/fr/about`) vers leurs versions localisées plus esthétiques (par exemple, `/fr/a-propos`).

**Exemple de Configuration :**

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

Cette fonctionnalité est prise en charge dès la sortie de la boîte dans **Next.js** et **Vite** via les proxys Intlayer, et peut être facilement intégrée dans d'autres routeurs comme **TanStack Router**, **React Router**, **Vue Router**, **SvelteKit**, et **Solid Router**.

Pour plus d'informations et des guides d'intégration, consultez la [Documentation sur les Réécritures d'URL Personnalisées](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/custom_url_rewrites.md).

---

### Valeurs d'Insertion Améliorées

En v8, les valeurs d'insertion peuvent désormais **accepter des éléments React (ou des nœuds Vue)** en plus des chaînes de caractères et des nombres. Cela vous permet d'injecter des composants riches et interactifs directement dans vos modèles d'insertion.

Intlayer gère désormais de manière robuste les nœuds React et Preact imbriqués dans les insertions, garantissant que les structures d'interface utilisateur complexes sont préservées et rendues correctement.

**Exemple :**

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

export default {
  key: "my-key",
  content: {
    myInsertion: insert("Hi {{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, // nombre
          // ou
          name: "John", // chaîne
          // ou
          name: <span>John</span>, // élément React
        })}
      </div>
    );
    ```

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

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

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

    return (
      <div>
        {myInsertion({
          name: 2, // nombre
          // ou
          name: "John", // chaîne
          // ou
          name: <span>John</span>, // élément 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,
            // ou
            name: 'John',
            // ou
            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, // nombre
          // ou
          name: "John", // chaîne
          // ou
          name: <span>John</span>, // élément Preact
        })}
      </div>
    );
    ```

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

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

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

    return (
      <div>
        {myInsertion({
          name: 2, // nombre
          // ou
          name: "John", // chaîne
          // ou
          name: <span>John</span>, // élément 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, // nombre
        // ou
        name: "John", // chaîne
      })}
    </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>

## Validation du Schéma de Contenu

Intlayer v8 introduit la validation de schéma pour les dictionnaires. Vous pouvez désormais définir des schémas de validation réutilisables dans votre configuration à l'aide de Zod et les appliquer à vos fichiers de contenu. Cela garantit que votre contenu respecte toujours la structure attendue, capturant les erreurs au moment de la construction.

### 1. Définir des Schémas

Définissez vos schémas dans `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. Appliquer des Schémas aux Dictionnaires

Référencez la clé du schéma dans la définition de votre dictionnaire :

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

const aboutPageMetaContent = {
  key: "about-page-meta",
  schema: "seo-metadata", // <--
  content: {
    title: "About Our Company - Learn More About Us",
    description: "Discover our company's mission, values, and team.",
  },
} satisfies Dictionary<"seo-metadata">;

export default aboutPageMetaContent;
```

Si le contenu ne correspond pas au schéma (par exemple, le titre est trop court), le processus de construction générera une erreur.

---

### Détection Automatique du Contenu Améliorée

En v8, Intlayer détecte intelligemment la syntaxe Markdown, les balises HTML et les insertions de variables dans vos chaînes de contenu. Cela signifie que vous pouvez souvent omettre les fonctions d'aide comme `md()`, `html()`, ou `insert()`.

Ce comportement est activé par défaut. Vous pouvez désormais affiner cette détection soit globalement dans votre `intlayer.config.ts`, soit par dictionnaire.

#### Contrôle Granulaire

Vous pouvez activer ou désactiver des types spécifiques de transformations :

```typescript fileName="intlayer.config.ts"
export default {
  dictionary: {
    // contentAutoTransformation: false (default)
    contentAutoTransformation: {
      markdown: true,
      html: true,
      insertion: false, // Désactiver la détection automatique des insertions
    },
  },
};
```

**Comportement v7 (enveloppement manuel) :**

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

export default {
  key: "my-key",
  content: {
    myMarkdown: md("## Hello World"),
    myInsertion: insert("Hi {{name}}"),
  },
};
```

**Comportement v8 (détection automatique) :**

```typescript fileName="src/example.content.ts"
export default {
  key: "my-key",
  contentAutoTransformation: true, // Peut aussi être défini par la définition du dictionnaire ou globalement dans intlayer.config.ts
  content: {
    myMarkdown: "## Hello World", // Détecté automatiquement comme Markdown
    myHTML: "<p>Hello World</p>", // Détecté automatiquement comme HTML
    myInsertion: "Hi {{name}}", // Détecté automatiquement comme Insertion
  },
};
```

Le résultat JSON sous-jacent reste le même, préservant les informations de type riches nécessaires au rendu :

```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}}"
    }
  }
}
```

---

## Localisation : nouveau hook `useIntl`

Un nouveau hook `useIntl()` est désormais disponible dans React, Next.js et Vue. Il fournit un objet `Intl` lié à la locale qui utilise automatiquement la langue actuelle pour formater les nombres, les dates, et plus encore, sans avoir besoin de passer manuellement la 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>

---

## Outils : Améliorations de l'Extension VSCode

L'extension VSCode d'Intlayer reçoit des mises à jour majeures en v8 pour rationaliser votre flux de travail d'internationalisation :

- **Temps de Démarrage** : Améliorations des performances lors de l'ouverture d'un projet.
- **Mise en Cache** : Couche de mise en cache améliorée pour une validation et une autocomplétion quasi instantanées.
- **Détection des Clés Inutilisées & des Clés Dupliquées** : Nouvelles fonctionnalités pour détecter automatiquement les **clés inutilisées** et les **clés dupliquées** à travers vos dictionnaires, vous aidant à garder votre contenu propre et efficace.

---

## Optimisations du Compilateur

Intlayer v8 inclut une nouvelle couche de mise en cache pour le compilateur Markdown et HTML. Cela garantit que les chaînes de contenu identiques avec la même configuration ne sont analysées qu'une seule fois, réduisant considérablement la surcharge lors des re-rendus ou lors de l'utilisation du même contenu à plusieurs endroits.

<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: [
        // Extraire le contenu des composants dans les dictionnaires
        [intlayerExtractBabelPlugin, getExtractPluginOptions()],
        // Optimiser les importations en remplaçant useIntlayer par des importations directes de dictionnaires
        [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()],
    });
    ```

> Pour vue / svelte, vous devrez installer le package de compilateur approprié :
>
> ```bash
> # Pour Vue
> npm install @intlayer/vue-compiler
> ```
>
> ```bash
> # Pour Svelte
> npm install @intlayer/svelte-compiler
> ```

  </Tab>
</Tabs>

---

## Flexibilité : Mode d'Importation Unifié

La propriété booléenne `live` a été dépréciée au profit d'une propriété `importMode` plus complète. Cela permet une définition explicite de la manière dont les dictionnaires doivent être chargés : statiquement, dynamiquement ou via la synchronisation en direct.

### Modes

- **`static`** (Par défaut) : Le dictionnaire est bundlé au moment de la construction. Idéal pour les performances.
- **`dynamic`** : Le dictionnaire est chargé à l'exécution (par exemple, via un fetch JSON ou suspense).
- **`fetch`** : Le dictionnaire est récupéré du CMS/Serveur à l'exécution et synchronisé.

**Migration :**

| Config v7     | Config v8                             |
| :------------ | :------------------------------------ |
| `live: true`  | `importMode: 'fetch'`                 |
| `live: false` | `importMode: 'static'` (ou 'dynamic') |

Note : Dans Intlayer v8, la propriété `importMode` a été déplacée de la configuration `build` vers la configuration `dictionary` dans `intlayer.config.ts`. Cela vous permet de définir un mode d'importation par défaut pour tous vos dictionnaires tout en pouvant le remplacer par dictionnaire.

**Exemple de Configuration Globale :**

```typescript fileName="intlayer.config.ts"
export default {
  dictionary: {
    importMode: "dynamic", // Par défaut global
  },
  // ...
};
```

**Exemple de Dictionnaire :**

```typescript fileName="src/example.content.ts"
export default {
    key: 'my-key',
    importMode: "fetch", // Remplace la config globale
    content: { ... }
}
```

---

## Contrôle de l'Emplacement du Dictionnaire

La v8 introduit la propriété `location` pour gérer explicitement où vivent les dictionnaires et comment ils se synchronisent. C'est particulièrement utile pour les flux de travail hybrides impliquant à la fois des fichiers locaux et du contenu CMS distant.

### Options

- **`local`** : Le dictionnaire existe uniquement localement. Il ne sera pas poussé vers le CMS distant.
- **`remote`** : Le dictionnaire est géré à distance. Une fois poussé sur le CMS, il sera détaché du local. Le dictionnaire distant sera récupéré du CMS.
- **`local_and_remote`** : Le dictionnaire existe aux deux endroits. Les changements locaux sont poussés, et les changements distants sont récupérés (synchronisés).

**Exemple :**

```typescript fileName="src/example.content.ts"
export default {
    key: 'my-key',
    location: "local", // Garder ce dictionnaire uniquement local
    content: { ... }
}
```

---

## Séparation de la Configuration Système

Intlayer v8 sépare la configuration des sources de contenu des chemins internes du système et de sortie. Cela désencombre la propriété `content` et rend clair quels paramètres sont destinés à la gestion par l'utilisateur par rapport à ceux gérés par le système Intlayer.

Les propriétés suivantes ont été déplacées de `content` vers une nouvelle propriété `system` dans `intlayer.config.ts` :

- `dictionariesDir`
- `moduleAugmentationDir`
- `unmergedDictionariesDir`
- `typesDir`
- `mainDir`
- `configDir`
- `cacheDir`
- `outputFilesPatternWithPath`

**Comportement v7 :**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src"],
    dictionariesDir: ".intlayer/dictionary", // Mélangé avec la config source
  },
};
```

**Comportement v8 :**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src"],
  },
  system: {
    dictionariesDir: ".intlayer/dictionary", // Clairement séparé
  },
};
```

---

## Séparation des Répertoires de Contenu et de Code

Intlayer v8 sépare la configuration pour les fichiers de définition de contenu de la configuration pour la transformation du code. Cela permet une surveillance et un balayage plus précis, améliorant les performances de construction.

Auparavant, `contentDir` était utilisé à la fois pour surveiller les fichiers `.content.*` et pour balayer le code pour les appels `useIntlayer`. Désormais :

- **`contentDir`** : Spécifiquement pour vos fichiers de déclaration de contenu.
- **`codeDir`** : Spécifiquement pour le code de votre application qui nécessite une transformation (par exemple, élagage, optimisation).

**Migration :**

Si vous aviez précédemment défini `contentDir`, Intlayer v8 l'utilisera également par défaut pour `codeDir`, mais enregistrera un avertissement. Vous devriez définir explicitement `codeDir` dans votre configuration.

**Comportement v7 :**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src", "@packages/design-system"], // Utilisé pour le contenu et le code
  },
};
```

**Comportement v8 :**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src/content", "@packages/design-system"], // Surveiller uniquement les fichiers src/content/*.content.* ici et les fichiers @packages/design-system/dist/*.content.*
    codeDir: ["src", "@packages/design-system"], // Balayer uniquement pour la transformation de code ici et les fichiers @packages/design-system/src/*.content.*
  },
};
```

---

## Framework : Améliorations Svelte

Le contenu Markdown et HTML dans Svelte s'analyse désormais automatiquement en HTML lorsqu'il est transformé en chaîne. Cela facilite beaucoup l'utilisation de la syntaxe `{@html}` de Svelte, car vous pouvez désormais simplement passer le nœud de contenu directement.

---

## Notes de migration depuis la v7

### Changements de Configuration

- **Propriété `live`** : La propriété `live` dans les dictionnaires est supprimée. Utilisez `importMode: 'fetch'` à la place.
- **importMode** : La propriété `build.importMode` dans la configuration a été dépréciée. Utilisez `dictionary.importMode` à la place.
- **`contentDir` et `codeDir`** : `contentDir` est désormais spécifiquement pour les fichiers de contenu. Une nouvelle propriété `codeDir` a été ajoutée pour la transformation du code. Si `codeDir` n'est pas défini, Intlayer reviendra à `contentDir` et enregistrera un avertissement.
- **Validation de Schéma** : Pour utiliser la nouvelle fonctionnalité `schema`, assurez-vous d'avoir `zod` installé dans votre projet.

---

## Liens utiles

- [Référence de Configuration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/configuration.md)
- [Documentation du Fichier de Contenu](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/content_file.md)
- [Documentation du Contenu HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/html.md)
- [Documentation du Contenu Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/markdown.md)
- [Documentation des Réécritures d'URL Personnalisées](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/custom_url_rewrites.md)
