---
createdAt: 2025-09-22
updatedAt: 2026-01-26
title: Novo Intlayer v8 - O que há de novo?
description: Descubra as novidades do Intlayer v8. Principais melhorias na experiência do desenvolvedor, validação de esquemas e gestão de dicionários.
keywords:
  - Intlayer
  - CMS
  - Experiência do desenvolvedor
  - Recursos
  - React
  - Next.js
  - JavaScript
  - TypeScript
youtubeVideo: https://www.youtube.com/watch?v=ia6JmVf-kkU
slugs:
  - doc
  - releases
  - v8
---

# Novo Intlayer v8 - O que há de novo?

Bem-vindo ao Intlayer v8! Esta versão foca em aprimorar a experiência do desenvolvedor com detecção automática de conteúdo, garantir a integridade dos dados com validação de esquemas e oferecer mais controlo sobre a gestão de dicionários.

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

## Índice

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

---

## Evolução do Conteúdo Rico: Markdown & HTML

O Intlayer v8 traz melhorias importantes na forma como o conteúdo rico é tratado, introduzindo os **nós HTML** (que não existiam na v7) e unificando a API com os **nós Markdown** (que existiam na v7 mas foram aprimorados).

### A API Unificada `.use()`

Introduzimos o método `.use()` para nós Markdown e HTML. Este método permite que você personalize as tags HTML ou componentes usados durante a renderização.

- **Substituição de Componentes**: Você pode facilmente substituir tags HTML ou componentes personalizados por seus próprios componentes de framework (por exemplo, substituir `<a>` por `NextLink` ou `<CustomCmp>` por um componente React).
- **Segurança de Tipos**: Todas as funções para fornecer componentes são totalmente tipadas, garantindo que você receba as props corretas.

### Comportamento de Renderização Padrão

Na v7, se nenhum provedor fosse definido, os nós Markdown eram renderizados como strings brutas, muitas vezes exigindo bibliotecas externas para analisá-los.

**Na v8, o Intlayer inclui seu próprio analisador Markdown interno.** Por padrão, os nós Markdown agora são renderizados diretamente como HTML sem a necessidade de bibliotecas externas.

### Novos Utilitários de Renderer & Provider

Introduzimos novas funções e componentes de renderização independentes para oferecer mais controlo fora do fluxo padrão do `useIntlayer`.

- **Markdown**: `MarkdownRenderer`, `useMarkdownRenderer`, `renderMarkdown`. (Nota: o `MarkdownProvider` existia na v7 mas agora se integra com essas novas ferramentas).
- **HTML**: `HTMLRenderer`, `useHTMLRenderer`, `renderHTML`, `HTMLProvider`.

#### Exemplos: Ferramentas de Renderização Markdown

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

    **1. Usando o Componente:**

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

    <MarkdownRenderer
      forceBlock={true}
      components={{
        h1: ({ children }) => <h1 className="text-2xl">{children}</h1>
      }}
    >
      {"# Meu Título"}
    </MarkdownRenderer>
    ```

    **2. Usando o Hook:**

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

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

    return <div>{renderMarkdown("# Meu Título")}</div>;
    ```

    **3. Usando a Função Utilitária:**

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

    const html = renderMarkdown("# Meu Título", {
      forceBlock: true
    });
    ```

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

    **1. Usando o Componente:**

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

    <template>
      <MarkdownRenderer :forceBlock="true" content="# Meu Título" />
    </template>
    ```

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

    **1. Usando o Componente:**

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

    <MarkdownRenderer forceBlock={true} value="# Meu Título" />
    ```

    **2. Usando o Hook:**

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

    {@html render("# Meu Título")}
    ```

    **3. Usando a Função Utilitária:**

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

    {@html renderMarkdown("# Meu Título")}
    ```

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

    **1. Usando o Serviço:**

    ```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. Usando o Componente:**

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

    <MarkdownRenderer forceBlock={true}>
      {"# Meu Título"}
    </MarkdownRenderer>
    ```

    **2. Usando o Hook:**

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

    const render = useMarkdownRenderer();

    return <div>{render("# Meu Título")}</div>;
    ```

    **3. Usando a Função Utilitária:**

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

    return <div>{renderMarkdown("# Meu Título")}</div>;
    ```

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

    **1. Usando o Componente:**

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

    <MarkdownRenderer forceBlock={true}>
      {"# Meu Título"}
    </MarkdownRenderer>
    ```

    **2. Usando o Hook:**

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

    const render = useMarkdownRenderer();

    return <div>{render("# Meu Título")}</div>;
    ```

    **3. Usando a Função Utilitária:**

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

    return <div>{renderMarkdown("# Meu Título")}</div>;
    ```

  </Tab>
</Tabs>

#### Exemplos: Ferramentas de Renderização HTML

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

    **1. Usando o Componente:**

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

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

    **2. Usando o 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. Usando a Função Utilitária:**

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

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

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

    **1. Usando o Componente:**

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

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

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

    **1. Usando o Componente:**

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

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

    **2. Usando o Hook:**

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

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

    **3. Usando a Função Utilitária:**

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

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

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

    **1. Uso Direto:**

    No Angular, você pode usar o binding padrão `[innerHTML]`.

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

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

    **1. Usando o Componente:**

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

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

    **2. Usando o Hook:**

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

    const render = useHTMLRenderer();

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

    **3. Usando a Função Utilitária:**

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

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

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

    **1. Usando o Componente:**

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

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

    **2. Usando o Hook:**

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

    const render = useHTMLRenderer();

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

    **3. Usando a Função Utilitária:**

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

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

  </Tab>
</Tabs>

Para mais detalhes, consulte a [Documentação de Conteúdo HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/html.md) e a [Documentação de Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/markdown.md).

---

## Reescritas de URL Personalizadas

O Intlayer v8 introduz suporte para **Reescritas de URL Personalizadas**, permitindo que você defina caminhos específicos por localidade que diferem da estrutura padrão `/locale/path`. Este é um recurso poderoso para melhorar o local SEO e proporcionar uma experiência de usuário mais natural para usuários que não falam inglês.

**Principais melhorias na v8:**

- **Framework Formatters**: Novos `nextjsRewrite`, `svelteKitRewrite`, `reactRouterRewrite`, `vueRouterRewrite`, `solidRouterRewrite`, `tanstackRouterRewrite`, `nuxtRewrite`, e `viteRewrite` para fornecer sintaxe de padrão idiomática para cada router.
- **`useRewriteURL` Hook**: Um novo hook do lado do cliente que corrige silenciosamente la barra de endereços para a URL localizada "bonita" sem acionar navegações do roteador.
- **Redirecionamentos automáticos de SEO**: Proxies embutidos agora redirecionam automaticamente os usuários de caminhos canônicos digitados manualmente (por exemplo, `/fr/about`) para suas versões localizadas mais amigáveis (por exemplo, `/fr/a-propos`).

**Exemplo de Configuração:**

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

Este recurso é suportado nativamente no **Next.js** e no **Vite** através dos proxies do Intlayer, e pode ser facilmente integrado em outros routers como **TanStack Router**, **React Router**, **Vue Router**, **SvelteKit** e **Solid Router**.

Para mais informações e guias de integração, veja a [Documentação de Reescritas de URL Personalizadas](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/custom_url_rewrites.md).

---

### Valores de Inserção Aprimorados

Na v8, os valores de inserção podem agora **aceitar elementos React (ou nós Vue)** além de strings e números. Isso permite que você injete componentes ricos e interativos diretamente em seus modelos de inserção.

O Intlayer agora lida de forma robusta com nós React e Preact aninhados dentro de inserções, garantindo que estruturas de UI complexas sejam preservadas e renderizadas corretamente.

**Exemplo:**

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

export default {
  key: "my-key",
  content: {
    myInsertion: insert("Olá {{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, // número
          // ou
          name: "John", // string
          // ou
          name: <span>John</span>, // elemento React
        })}
      </div>
    );
    ```

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

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

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

    return (
      <div>
        {myInsertion({
          name: 2, // número
          // ou
          name: "John", // string
          // ou
          name: <span>John</span>, // elemento 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, // número
            // ou
            name: 'John', // string
            // ou
            name: h('span', 'John'), // nó Vue
          })"
        />
      </div>
    </template>
    ```

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

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

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

    return (
      <div>
        {myInsertion({
          name: 2, // número
          // ou
          name: "John", // string
          // ou
          name: <span>John</span>, // elemento Preact
        })}
      </div>
    );
    ```

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

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

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

    return (
      <div>
        {myInsertion({
          name: 2, // número
          // ou
          name: "John", // string
          // ou
          name: <span>John</span>, // elemento 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, // número
        // ou
        name: "John", // string
      })}
    </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>

## Validação de Esquema de Conteúdo

O Intlayer v8 introduz a validação de esquema para dicionários. Agora você pode definir esquemas de validação reutilizáveis em sua configuração usando Zod e aplicá-los aos seus arquivos de conteúdo. Isso garante que seu conteúdo sempre adira à estrutura esperada, capturando erros em tempo de build.

### 1. Definir Esquemas

Defina seus esquemas em `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. Aplicar Esquemas a Dicionários

Referencie a chave do esquema em sua definição de dicionário:

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

const aboutPageMetaContent = {
  key: "about-page-meta",
  schema: "seo-metadata", // <--
  content: {
    title: "Sobre Nossa Empresa - Saiba Mais Sobre Nós",
    description: "Descubra a missão, os valores e a equipa da nossa empresa.",
  },
} satisfies Dictionary;

export default aboutPageMetaContent;
```

Se o conteúdo não corresponder ao esquema (por exemplo, o título é muito curto), o processo de build gerará um erro.

---

### Detecção Automática de Conteúdo Aprimorada

Na v8, o Intlayer detecta inteligentemente a sintaxe Markdown, tags HTML e inserções de variáveis em suas strings de conteúdo. Isso significa que muitas vezes você pode omitir funções auxiliares como `md()`, `html()` ou `insert()`.

Este comportamento está ativado por padrão. Agora você pode ajustar essa detecção globalmente em seu `intlayer.config.ts` ou por dicionário.

#### Controlo Granular

Você pode ativar ou desativar tipos específicos de transformações:

```typescript fileName="intlayer.config.ts"
export default {
  dictionary: {
    // contentAutoTransformation: false (default)
    contentAutoTransformation: {
      markdown: true,
      html: true,
      insertion: false, // Desativar a detecção automática de inserções
    },
  },
};
```

**Comportamento v7 (Encapsulamento manual):**

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

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

**Comportamento v8 (Detecção automática):**

```typescript fileName="src/example.content.ts"
export default {
  key: "my-key",
  contentAutoTransformation: true, // Também pode ser definido pela definição do dicionário ou globalmente em intlayer.config.ts
  content: {
    myMarkdown: "## Hello World", // Detectado automaticamente como Markdown
    myHTML: "<p>Hello World</p>", // Detectado automaticamente como HTML
    myInsertion: "Olá {{name}}", // Detectado automaticamente como Inserção
  },
};
```

O resultado JSON subjacente permanece o mesmo, preservando a rica informação de tipo necessária para a renderização:

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

---

## Localização: novo hook `useIntl`

Um novo hook `useIntl()` está agora disponível em React, Next.js e Vue. Ele fornece um objeto `Intl` vinculado à localidade que usa automaticamente o idioma atual para formatar números, datas e mais, sem necessidade de passar a localidade manualmente.

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

---

## Ferramentas: Melhorias na Extensão VSCode

A extensão Intlayer para VSCode recebe atualizações significativas na v8 para otimizar o seu fluxo de trabalho de internacionalização:

- **Tempo de Inicialização**: Melhorias de desempenho ao abrir um projeto.
- **Cache**: Camada de cache melhorada para validação e autocompletação quase instantâneas.
- **Detecção de Chaves Não Utilizadas & Chaves Duplicadas**: Novas funcionalidades para detectar automaticamente **chaves não utilizadas** e **chaves duplicadas** em todos os seus dicionários, ajudando a manter o seu conteúdo limpo e eficiente.

---

## Otimizações do Compilador

Intlayer v8 inclui uma nova camada de cache para o compilador Markdown e HTML. Isso garante que strings de conteúdo idênticas com a mesma configuração sejam analisadas apenas uma vez, reduzindo significativamente a sobrecarga durante re-renders ou quando o mesmo conteúdo é usado em vários lugares.

<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: [
        // Extrair conteúdo de componentes para os dicionários
        [intlayerExtractBabelPlugin, getExtractPluginOptions()],
        // Otimiza as importações substituindo useIntlayer por importações diretas de dicionários
        [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()],
    });
    ```

> Para Vue / Svelte será necessário instalar o pacote de compilador apropriado:
>
> ```bash
> # Para Vue
> npm install @intlayer/vue-compiler
> ```
>
> ```bash
> # Para Svelte
> npm install @intlayer/svelte-compiler
> ```

  </Tab>
</Tabs>

---

## Flexibilidade: Modo Unificado de Importação

A propriedade booleana `live` foi descontinuada em favor de uma propriedade mais abrangente `importMode`. Isso permite a definição explícita de como os dicionários devem ser carregados: estaticamente, dinamicamente ou via sincronização ao vivo.

### Modos

- **`static`** (Padrão): O dicionário é empacotado em tempo de build. Melhor para desempenho.
- **`dynamic`**: O dicionário é carregado em tempo de execução (por exemplo, via fetch de JSON ou suspense).
- **`fetch`**: O dicionário é buscado do CMS/Server em tempo de execução e sincronizado.

**Geçiş:**

| Configuração v7 | Configuração v8                       |
| :-------------- | :------------------------------------ |
| `live: true`    | `importMode: 'fetch'`                 |
| `live: false`   | `importMode: 'static'` (ou 'dynamic') |

Nota: No Intlayer v8, a propriedade `importMode` foi movida da configuração `build` para a configuração `dictionary` em `intlayer.config.ts`. Isso permite definir um modo de importação padrão para todos os seus dicionários, ao mesmo tempo em que ainda é possível sobrescrevê-lo por dicionário.

**Exemplo de Configuração Global:**

```typescript fileName="intlayer.config.ts"
export default {
  dictionary: {
    importMode: "dynamic", // Padrão global
  },
  // ...
};
```

**Exemplo de Dicionário:**

```typescript fileName="src/example.content.ts"
export default {
    key: 'my-key',
    importMode: "fetch", // Sobrescreve a configuração global
    content: { ... }
}
```

---

## Controlo da Localização do Dicionário

v8 introduz a propriedade `location` para gerir explicitamente onde os dicionários residem e como eles se sincronizam. Isto é particularmente útil para fluxos de trabalho híbridos envolvendo tanto ficheiros locais quanto conteúdo de CMS remoto.

### Opções

- **`local`**: O dicionário existe apenas localmente. Não será enviado para o CMS remoto.
- **`remote`**: O dicionário é gerido remotamente. Uma vez enviado para o CMS, será desvinculado do local. O dicionário remoto será obtido a partir do CMS.
- **`local_and_remote`**: O dicionário existe em ambos os locais. Alterações locais são enviadas, e alterações remotas são obtidas (sincronizadas).

**Exemplo:**

```typescript fileName="src/example.content.ts"
export default {
    key: 'my-key',
    location: "local", // Mantenha este dicionário apenas local
    content: { ... }
}
```

---

## Separação da Configuração do Sistema

Intlayer v8 separa a configuração das fontes de conteúdo dos caminhos internos do sistema e de saída. Isso desobstrui a propriedade `content` e deixa claro quais configurações são destinadas ao gerenciamento pelo usuário versus as que são gerenciadas pelo sistema Intlayer.

As seguintes propriedades foram movidas de `content` para uma nova propriedade `system` em `intlayer.config.ts`:

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

**Comportamento v7:**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src"],
    dictionariesDir: ".intlayer/dictionary", // Misturado com a configuração de origem
  },
};
```

**Comportamento v8:**

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

---

## Separação de Diretórios de Conteúdo e Código

O Intlayer v8 separa a configuração dos ficheiros de definição de conteúdo da configuração para transformação de código. Isto permite uma monitorização e varredura mais precisas, melhorando o desempenho da build.

Anteriormente, `contentDir` era usado tanto para monitorizar ficheiros `.content.*` como para escanear o código à procura de chamadas a `useIntlayer`. Agora:

- **`contentDir`**: Especificamente para os seus ficheiros de declaração de conteúdo.
- **`codeDir`**: Especificamente para o código da sua aplicação que necessita de transformação (por exemplo, pruning, optimization).

**Migração:**

Se anteriormente você tinha `contentDir` definido, o Intlayer v8 o usará como padrão para `codeDir` também, mas registrará um aviso. Você deve definir explicitamente `codeDir` na sua configuração.

**Comportamento v7:**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src", "@packages/design-system"], // Usado tanto para conteúdo quanto para código
  },
};
```

**Comportamento v8:**

```typescript fileName="intlayer.config.ts"
export default {
  content: {
    contentDir: ["src/content", "@packages/design-system"], // Somente observa arquivos src/content/*.content.* e @packages/design-system/dist/*.content.* aqui
    codeDir: ["src", "@packages/design-system"], // Somente escaneia para transformação de código aqui e arquivos @packages/design-system/src/*.content.*
  },
};
```

---

## Framework: Melhorias no Svelte

Conteúdo Markdown e HTML no Svelte agora é automaticamente convertido para HTML quando convertido em string. Isso facilita muito o uso com a sintaxe `{@html}` do Svelte, pois agora você pode simplesmente passar o nó de conteúdo diretamente.

---

## Notas de migração da v7

### Alterações na Configuração

- **Propriedade `live`**: A propriedade `live` em dicionários foi removida. Use `importMode: 'fetch'` em vez disso.
- **importMode**: A propriedade `build.importMode` na configuração foi obsoleta. Use `dictionary.importMode` em vez disso.
- **`contentDir` e `codeDir`**: `contentDir` agora é especificamente para ficheiros de conteúdo. Foi adicionada uma nova propriedade `codeDir` para transformação de código. Se `codeDir` não estiver definido, o Intlayer recorrerá a `contentDir` como fallback e registará um aviso.
- **Validação de Schema**: Para utilizar a nova funcionalidade `schema`, assegure-se de ter o `zod` instalado no seu projeto.

---

## Links úteis

- [Referência de Configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md)
- [Documentação do Ficheiro de Conteúdo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/content_file.md)
- [Documentação de Conteúdo HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/html.md)
- [Documentação de Conteúdo Markdown](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dictionary/markdown.md)
- [Documentação de Reescritas Personalizadas de URLs](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/custom_url_rewrites.md)
