Autor:
    Criação:2025-09-22Última atualização:2026-06-14

    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.

    www.youtube.com

    Índice


    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

    1. Usando o Componente:

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";<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/markdown";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/markdown";const html = renderMarkdown("# Meu Título", {  forceBlock: true});

    Exemplos: Ferramentas de Renderização HTML

    1. Usando o Componente:

    tsx
    import { HTMLRenderer } from "react-intlayer/html";<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/html";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/html";const html = renderHTML("<p>Hello World</p>");

    Para mais detalhes, consulte a Documentação de Conteúdo HTML e a Documentação de Markdown.


    Ficheiros de Conteúdo YAML & Markdown (v8.10.0)

    Agora pode declarar conteúdo diretamente usando as extensões de ficheiro .content.md e .content.yaml. Isto é perfeito para conteúdos longos, blogs, documentação e políticas de privacidade.

    Estes ficheiros são totalmente editáveis a partir do Visual Editor, proporcionando um fluxo de trabalho simplificado para membros não técnicos da equipa.

    Para mais detalhes, consulte a Documentação de Ficheiros de Conteúdo YAML e a Documentação de Ficheiros de Conteúdo Markdown.


    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:

    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;

    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.


    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:

    src/example.content.ts
    import { insert } from "intlayer";export default {  key: "my-key",  content: {    myInsertion: insert("Olá {{name}}"),  },};
    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>);

    Regras de Plural Unicode CLDR (v8.8.0)

    Foi introduzido um novo helper de nó plural baseado nas regras de plural definidas pelo Projeto Unicode CLDR, melhorando o suporte para idiomas complexos.

    src/openings.content.ts
    import { plural, t, type Dictionary } from "intlayer";const openingsContent = {  key: "total_openings",  content: {    totalOpenings: t({      en: plural({        one: "{{count}} opening",        other: "{{count}} openings",      }),      fr: plural({        one: "{{count}} offre",        other: "{{count}} offres",      }),    }),  },} satisfies Dictionary;export default openingsContent;

    Você pode então passar a contagem dinamicamente no componente do seu framework:

    tsx
    import type { FC } from "react";import { useIntlayer } from "react-intlayer";const OpeningsComponent: FC<{ count: number }> = ({ count }) => {  const { totalOpenings } = useIntlayer("total_openings");  return (    <div>      {/* Em Inglês:                                  */}      {/*  count=0  → "0 openings"   (other)           */}      {/*  count=1  → "1 opening"    (one)             */}      {/*  count=2  → "2 openings"   (other)           */}      {/*  count=21 → "21 openings"  (other)           */}      <p>{totalOpenings(count)}</p>    </div>  );};

    Para mais informações, consulte a Documentação de Pluralização.


    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:

    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:

    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.


    TypeScript: Acessores Primitivos IntlayerNode

    O tipo IntlayerNode foi atualizado para permitir a chamada de métodos JavaScript primitivos diretamente nos nós de conteúdo. Isto torna possível interagir com o seu conteúdo localizado diretamente como se fosse uma primitiva padrão de string, number, boolean ou array.

    Suportado em React, Preact, Solid, Svelte, Vue e Angular.

    Exemplo de String

    typescript
    content.placeholder; // Retorna IntlayerNode<string>content.placeholder.value; // Retorna stringcontent.placeholder.toString(); // Retorna stringcontent.placeholder.toLowerCase(); // Retorna stringString(content.placeholder); // Retorna stringcontent.placeholder.toUpperCase(); // Retorna string em maiúsculascontent.placeholder.replace("a", "b"); // Retorna string modificada

    Exemplo de Array

    typescript
    content.myArrayOfString             // Retorna IntlayerNode<Array<string>>content.myArrayOfString.find(...)   // Retorna elementocontent.myArrayOfString.join(', ')  // Retorna string unida

    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:

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

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

    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.

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

    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.

    Ferramentas: Watcher C++ & LSP baseado em OXC (v8.12.0)

    O Intlayer v8.12.0 traz grandes melhorias para a experiência do desenvolvedor:

    • Parcel Watcher: O watcher de conteúdo foi migrado de chokidar para @parcel/watcher, aproveitando a monitorização nativa de ficheiros em C++ para fornecer atualizações mais rápidas e um consumo de memória significativamente menor.
    • Novo Language Server Protocol (LSP): Um novo LSP está agora disponível. Construído com análise baseada em OXC, ajuda o seu IDE e agentes de IA a ligar perfeitamente as chamadas useIntlayer('my-key') aos seus ficheiros .content correspondentes, e vice-versa.

    Para mais detalhes, consulte a Documentação do LSP.


    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.

    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()],  ],};

    Otimizações de Build Experimentais: Minify & Purge (v8.7.0)

    O Intlayer v8.7.0 introduz novos recursos experimentais de build no seu intlayer.config.ts projetados para otimizar o seu bundle de produção:

    • Minimização de Dicionários (Minify): Minimiza os ficheiros de dicionário para reduzir o tamanho.
    • Purga de Chaves Não Utilizadas (Purge): Varre e remove chaves de tradução não utilizadas dos dicionários, renomeando as chaves ativas para caracteres curtos (por exemplo, "products" -> "a", "pricing" -> "b"). Isto reduz o tamanho do bundle em até 5%.
    • Desativar Verificações TypeScript: Acelera as builds desativando a verificação de tipos TypeScript durante a etapa de compilação.
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH],    defaultLocale: Locales.ENGLISH,  },  dictionary: {    importMode: "dynamic",  },  build: {    /**     * Minimiza os dicionários para reduzir o tamanho do bundle.     */    minify: true,    /**     * Purga as chaves não utilizadas nos dicionários     */    purge: true,    /**     * Indica se a build deve verificar os tipos TypeScript     */    checkTypes: false,  },};export default config;

    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:

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

    Exemplo de Dicionário:

    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:

    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:

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

    Comportamento v8:

    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:

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

    Comportamento v8:

    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.


    Suporte Angular: Vite Bundler (v8.11.0)

    Para utilizadores do Angular, o Intlayer agora suporta nativamente o bundler Vite através de um novo plugin esbuild personalizado, acelerando os tempos de desenvolvimento e build.

    Para detalhes sobre a configuração, consulte a Documentação do Ambiente Angular.


    Geração de Sitemap (v8.6.0)

    O Intlayer agora gera sitemaps automaticamente com base nas suas localidades e modo de roteamento. Isto é particularmente útil para otimização de SEO em arquiteturas de roteador como o TanStack Router:

    src/routes/sitemap.xml.ts
    import { createFileRoute } from "@tanstack/react-router";import { generateSitemap } from "intlayer";const SITE_URL = (  import.meta.env.VITE_SITE_URL ?? "http://localhost:3000").replace(/\/$/, "");export const Route = createFileRoute("/sitemap.xml")({  server: {    handlers: {      GET: async () => {        const sitemap = generateSitemap(          [            { path: "/", changefreq: "daily", priority: 1.0 },            { path: "/about", changefreq: "monthly", priority: 0.8 },          ],          { siteUrl: SITE_URL }        );        return new Response(sitemap, {          headers: { "Content-Type": "application/xml" },        });      },    },  },});

    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.