Autor:
    Criação:2026-04-24Última atualização:2026-08-30

    Traduza o seu site Astro + Svelte com o Intlayer | Internacionalização (i18n)

    ide.intlayer.org
    intlayer-astro-template.vercel.app

    Índice

    Por que Intlayer em vez de alternativas?

    Comparado com soluções principais como astro-i18n ou i18next, Intlayer é uma solução que vem com otimizações integradas como:

    O Intlayer é otimizado para funcionar perfeitamente com o Astro, oferecendo roteamento multilíngue, mapa do site e todos os recursos necessários para dimensionar a internacionalização (i18n).

    Em vez de carregar arquivos JSON enormes em suas páginas, carregue apenas o conteúdo necessário. O Intlayer ajuda a reduzir o tamanho do bundle e das páginas em até 50%.

    Definir o escopo do conteúdo do seu aplicativo facilita a manutenção de aplicativos de grande escala. Você pode duplicar ou excluir uma única pasta de recursos sem o fardo mental de revisar toda a base de código de seu conteúdo. Além disso, o Intlayer é totalmente tipado (fully typed) para garantir a precisão do seu conteúdo.

    A co-localização de conteúdo reduz o contexto necessário pelos Large Language Models (LLMs). O Intlayer também vem com um conjunto de ferramentas, como uma CLI para testar traduções ausentes,LSP, MCP, e agent skills, para tornar a experiência do desenvolvedor (DX) ainda mais tranquila para os agentes de IA.

    Use a automação para traduzir seu pipeline de CI/CD usando o LLM de sua escolha às custas de seu provedor de IA. O Intlayer também oferece um compilador para automatizar a extração de conteúdo, bem como uma plataforma web para ajudar a traduzir em segundo plano.

    Conectar arquivos JSON enormes a componentes pode levar a problemas de desempenho e reatividade. O Intlayer otimiza o carregamento do seu conteúdo no momento da construção.

    Mais do que apenas uma solução i18n, o Intlayer fornece um [editor visual] auto-hospedado(/pt/doc/concept/editor)* e um *CMS completo para ajudá-lo a gerenciar seu conteúdo multilíngue em tempo real, facilitando a colaboração com tradutores, redatores e outros membros da equipe. O conteúdo pode ser armazenado local e/ou remotamente.

    Guia passo a passo para configurar o Intlayer no Astro + Svelte

    Confira o modelo da aplicação no GitHub.

    1. Instalar Dependências

      Instale os pacotes necessários usando seu gerenciador de pacotes preferido:

      bash
      npx intlayer init --interactive
      
      a flag --interactive é opcional. Use intlayer-cli init se você for um agente de IA.
      Este comando detectará seu ambiente e instalará os pacotes necessários. Por exemplo:
      bash
      npm install intlayer astro-intlayer svelte svelte-intlayer @astrojs/svelte
      
      • intlayer O pacote principal que fornece ferramentas de i18n para gerenciamento de configuração, traduções, declaração de conteúdo, transpilação e comandos CLI.

      • astro-intlayer Inclui o plugin de integração do Astro para vincular o Intlayer ao bundler Vite, bem como o middleware para detectar o idioma preferido do usuário, gerenciar cookies e lidar com redirecionamentos de URL.

      • svelte Pacote principal do Svelte.

      • svelte-intlayer Pacote para integrar o Intlayer em aplicações Svelte. Ele fornece o setupIntlayer, além dos stores useIntlayer e useLocale para internacionalização no Svelte.

      • @astrojs/svelte Integração oficial do Astro que permite o uso de islands de componentes Svelte.

    2. Configurar seu Projeto

      Crie um arquivo de configuração para definir os idiomas da sua aplicação:

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [
            Locales.ENGLISH,
            Locales.FRENCH,
            Locales.SPANISH,
            Locales.PORTUGUESE,
            // Seus outros idiomas
          ],
          defaultLocale: Locales.ENGLISH,
        },
      };
      
      export default config;
      
      Através deste arquivo de configuração, você pode configurar URLs localizadas, redirecionamentos de middleware, nomes de cookies, localização e extensões de declarações de conteúdo, desativar logs do Intlayer no console e muito mais. Para uma lista completa de parâmetros disponíveis, consulte a documentação de configuração.
    3. Integrar o Intlayer na sua configuração do Astro

      Adicione o plugin intlayer e a integração do Svelte à sua configuração do Astro.

      astro.config.ts
      // @ts-check
      
      import { intlayer } from "astro-intlayer";
      import svelte from "@astrojs/svelte";
      import { defineConfig } from "astro/config";
      
      // https://astro.build/config
      export default defineConfig({
        integrations: [intlayer(), svelte()],
      });
      
      O plugin de integração intlayer() é usado para integrar o Intlayer ao Astro. Ele garante a geração dos arquivos de declaração de conteúdo e os monitora em modo de desenvolvimento. Ele define variáveis de ambiente do Intlayer dentro da aplicação Astro e fornece aliases para otimizar o desempenho.
      A integração svelte() permite o uso de islands de componentes Svelte via client:only="svelte".
    4. Declarar seu conteúdo

      Crie e gerencie suas declarações de conteúdo para armazenar traduções:

      src/app.content.ts
      import { t, type Dictionary } from "intlayer";
      
      const appContent = {
        key: "app",
        content: {
          title: t({
            en: "Hello World",
            fr: "Bonjour le monde",
            es: "Hola mundo",
            pt: "Olá Mundo",
          }),
        },
      } satisfies Dictionary;
      
      export default appContent;
      
      As declarações de conteúdo podem ser definidas em qualquer lugar da sua aplicação, desde que estejam incluídas no contentDir (por padrão ./src) e correspondam à extensão do arquivo de declaração de conteúdo (por padrão .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Para mais informações, consulte a documentação de declaração de conteúdo.
    5. Usar o conteúdo no Astro

      Você pode consumir os dicionários diretamente nos seus arquivos .astro usando os ajudantes principais exportados do intlayer. Você também deve adicionar metadados de SEO (como hreflang e links canônicos) a cada página e introduzir uma island de Svelte para conteúdo interativo no lado do cliente.

      src/pages/[...locale]/index.astro
      ---
      import {
        getIntlayer,
        getLocaleFromPath,
        getLocalizedUrl,
        getHTMLTextDir,
        getPrefix,
        localeMap,
        defaultLocale,
        type LocalesValues,
      } from "intlayer";
      import SvelteIsland from "../../components/svelte/SvelteIsland.svelte";
      
      export const getStaticPaths = () => {
        return localeMap(({ locale }) => ({
          params: { locale: getPrefix(locale).localePrefix },
        }));
      };
      
      const locale = getLocaleFromPath(Astro.url.pathname) as LocalesValues;
      const { title } = getIntlayer("app", locale);
      ---
      
      <!doctype html>
      <html lang={locale} dir={getHTMLTextDir(locale)}>
        <head>
          <meta charset="utf-8" />
          <meta name="viewport" content="width=device-width" />
          <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
          <title>{title}</title>
      
          <!-- Link Canônico: informa aos motores de busca sobre a versão principal desta página -->
          <link
            rel="canonical"
            href={new URL(getLocalizedUrl(Astro.url.pathname, locale), Astro.site)}
          />
      
          <!-- Hreflang: informa ao Google sobre todas as versões localizadas -->
          {
            localeMap(({ locale: mapLocale }) => (
              <link
                rel="alternate"
                hreflang={mapLocale}
                href={new URL(
                  getLocalizedUrl(Astro.url.pathname, mapLocale),
                  Astro.site
                )}
              />
            ))
          }
      
          <!-- x-default: opção de fallback quando o idioma não corresponde ao do usuário -->
          <link
            rel="alternate"
            hreflang="x-default"
            href={new URL(
              getLocalizedUrl(Astro.url.pathname, defaultLocale),
              Astro.site
            )}
          />
        </head>
        <body>
          <!-- A island de Svelte renderiza todo o conteúdo interativo, incluindo o seletor de idioma -->
          <SvelteIsland locale={locale} client:only="svelte" />
        </body>
      </html>
      
      Se você quiser usar seu conteúdo em un atributo de string, como alt, title, href, aria-label, etc., você pode usar o valor da função, como:
      tsx
      <img src={content.image.src.value} alt={content.image.value} />
      <img src={content.image.src.toString()} alt={content.image.toString()} />
      <img src={String(content.image.src)} alt={String(content.image)} />
      

      Nota sobre a configuração de roteamento: A estrutura de diretórios que você usa depende da configuração middleware.routing no intlayer.config.ts:

      • prefix-no-default (padrão): mantém o idioma padrão na raiz (sem prefixo) e adiciona prefixos aos outros. Use [...locale] para capturar todos os casos.
      • prefix-all: todos os URLs recebem um prefixo de idioma. Você pode usar o padrão [locale] se não precisar lidar com a raiz separadamente.
      • search-param ou no-prefix: não são necessários diretórios de idioma. O idioma é tratado via parâmetros de consulta ou cookies.
    6. Criar um componente Island de Svelte

      Crie um componente de island que envolva sua aplicação Svelte. Você deve chamar o setupIntlayer com a localidade detectada pelo servidor antes de acessar os stores.

      src/components/svelte/SvelteIsland.svelte
      <script lang="ts">
        import { useIntlayer, useLocale, setupIntlayer } from "svelte-intlayer";
        import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";
      
        export let locale: LocalesValues;
      
        setupIntlayer(locale);
      
        const content = useIntlayer("app");
        const { locale: currentLocale, availableLocales, setLocale } = useLocale({
          onLocaleChange: (newLocale: LocalesValues) => {
            window.location.href = getLocalizedUrl(window.location.pathname, newLocale);
          },
        });
      </script>
      
      <div>
        <h1>{$content.title}</h1>
        <!-- O seletor de idioma é renderizado diretamente dentro da island -->
        <div class="locale-switcher">
          <span class="switcher-label">Mudar idioma:</span>
          <div class="locale-buttons">
            {#each availableLocales as localeItem}
              <button
                class="locale-btn {localeItem === $currentLocale ? 'active' : ''}"
                disabled={localeItem === $currentLocale}
                on:click={() => setLocale(localeItem)}
              >
                <span class="ls-own-name">{getLocaleName(localeItem)}</span>
                <span class="ls-current-name">{getLocaleName(localeItem, $currentLocale)}</span>
                <span class="ls-code">{localeItem.toUpperCase()}</span>
              </button>
            {/each}
          </div>
        </div>
      </div>
      
      A prop locale é passada da página Astro (detecção no servidor) e usada para inicializar o setupIntlayer, definindo o idioma inicial para todos os stores no componente.
    7. Adicionar um Seletor de Idioma

      A funcionalidade de troca de idioma está integrada diretamente na island de Svelte (veja o passo 6 acima). Ela usa o store useLocale do svelte-intlayer e navega para a URL localizada quando um usuário seleciona um novo idioma:

      src/components/svelte/SvelteIsland.svelte
      <script lang="ts">
        import { useLocale } from "svelte-intlayer";
        import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";
      
        // Reutiliza a mesma lógica de locale/setupIntlayer do passo 6...
      
        const {
          locale: currentLocale,
          availableLocales,
          setLocale,
        } = useLocale({
          onLocaleChange: (newLocale: LocalesValues) => {
            // Navega para a URL localizada ao mudar de idioma
            window.location.href = getLocalizedUrl(window.location.pathname, newLocale);
          },
        });
      </script>
      
      <div class="locale-switcher">
        <span class="switcher-label">Mudar idioma:</span>
        <div class="locale-buttons">
          {#each availableLocales as localeItem}
            <button
              class="locale-btn {localeItem === $currentLocale ? 'active' : ''}"
              disabled={localeItem === $currentLocale}
              on:click={() => setLocale(localeItem)}
            >
              <span class="ls-own-name">{getLocaleName(localeItem)}</span>
              <span class="ls-current-name">{getLocaleName(localeItem, $currentLocale)}</span>
              <span class="ls-code">{localeItem.toUpperCase()}</span>
            </button>
          {/each}
        </div>
      </div>
      

      Nota sobre persistência: O uso de onLocaleChange para redirecionar via window.location.href garante que a nova URL linguística seja visitada, permitindo que o middleware do Intlayer defina o cookie de idioma e lembre da preferência do usuário em visitas futuras.

    8. Sitemap e Robots.txt

      O Intlayer oferece utilitários para criar dinamicamente o seu sitemap localizado e os arquivos robots.txt.

      Sitemap

      O Intlayer vem com um gerador de sitemap integrado para ajudá-lo a criar facilmente um sitemap para sua aplicação. Ele cuida das rotas localizadas e adiciona os metadados necessários para os mecanismos de busca.

      O sitemap gerado pelo Intlayer suporta o namespace xhtml:link (Hreflang XML Extensions). Ao contrário dos geradores de sitemap padrão que apenas listam URLs brutos, o Intlayer cria automaticamente os links bidirecionais necessários entre todas as versões de idioma de uma página (por exemplo, /about, /about?lang=fr e /about?lang=es). Isso garante que os mecanismos de busca indexem e sirvam corretamente a versão de idioma certa para o público certo.

      Crie src/pages/sitemap.xml.ts para gerar um sitemap que inclua todas as suas rotas localizadas.

      src/pages/sitemap.xml.ts
      import type { APIRoute } from "astro";
      import { generateSitemap, type SitemapUrlEntry } from "intlayer";
      
      const pathList: SitemapUrlEntry[] = [
        { path: "/", changefreq: "daily", priority: 1.0 },
        { path: "/about", changefreq: "monthly", priority: 0.7 },
      ];
      
      const SITE_URL = import.meta.env.SITE ?? "http://localhost:4321";
      
      export const GET: APIRoute = async ({ site }) => {
        const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });
      
        return new Response(xmlOutput, {
          headers: { "Content-Type": "application/xml" },
        });
      };
      

      Robots.txt

      Crie src/pages/robots.txt.ts para controlar o rastreamento dos motores de busca.

      src/pages/robots.txt.ts
      import type { APIRoute } from "astro";
      import { getMultilingualUrls } from "intlayer";
      
      const getAllMultilingualUrls = (urls: string[]) =>
        urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);
      
      const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);
      
      export const GET: APIRoute = ({ site }) => {
        const robotsTxt = [
          "User-agent: *",
          "Allow: /",
          ...disallowedPaths.map((path) => `Disallow: ${path}`),
          "",
          `Sitemap: ${new URL("/sitemap.xml", site).href}`,
        ].join("\n");
      
        return new Response(robotsTxt, {
          headers: { "Content-Type": "text/plain" },
        });
      };
      
    9. Extrair o conteúdo dos seus componentes

      Opcional

      Se você tiver uma base de código existente, transformar milhares de arquivos pode ser demorado.

      Para facilitar esse processo, o Intlayer propõe um compilador / extrator para transformar seus componentes e extrair o conteúdo.

      Para configurá-lo, você pode adicionar uma seção compiler no seu arquivo intlayer.config.ts:

      intlayer.config.ts
      import { type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        // ... Resto da sua configuração
        compiler: {
          /**
           * Indica se o compilador deve ser ativado.
           */
          enabled: true,
      
          /**
           * Define o caminho dos arquivos de saída
           */
          output: ({ fileName, extension }) => `./${fileName}${extension}`,
      
          /**
           * Indica se os componentes devem ser salvos após serem transformados. Dessa forma, o compilador pode ser executado apenas uma vez para transformar o aplicativo e depois removido.
           */
          saveComponents: false,
      
          /**
           * Prefixo da chave do dicionário
           */
          dictionaryKeyPrefix: "",
        },
      };
      
      export default config;
      

      Execute o extrator para transformar seus componentes e extrair o conteúdo

      bash
      npx intlayer extract
      
      Since v9, the intlayerCompiler is included in the intlayer plugin. So you don't need to add it manually.

      Atualize seu vite.config.ts para incluir o plugin intlayerCompiler:

      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer, intlayerCompiler } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      
      bash
      npm run build # Ou npm run dev
      

    Configuração do TypeScript

    O Intlayer usa o aumento de módulos (module augmentation) para aproveitar o TypeScript, tornando sua base de código mais robusta.

    Preenchimento automático

    Erro de tradução

    Certifique-se de que sua configuração do TypeScript inclua os tipos gerados automaticamente.

    tsconfig.json
    {
      // ... sua configuração existente do TypeScript
      "include": [
        // ... sua configuração existente do TypeScript
        ".intlayer/**/*.ts", // Incluir tipos gerados automaticamente
      ],
    }
    

    Configuração do Git

    Recomenda-se ignorar os arquivos gerados pelo Intlayer. Isso evita committá-los no seu repositório Git.

    Para fazer isso, adicione as seguintes instruções ao seu arquivo .gitignore:

    bash
    # Ignorar os arquivos gerados pelo Intlayer
    .intlayer
    

    Extensão do VS Code

    Para melhorar sua experiência de desenvolvimento com o Intlayer, você pode instalar a extensão oficial do Intlayer para VS Code.

    Instalação pelo VS Code Marketplace

    Esta extensão fornece:

    • Preenchimento automático para chaves de tradução.
    • Detecção de erros em tempo real para traduções ausentes.
    • Visualização inline do conteúdo traduzido.
    • Ações rápidas para criar e atualizar traduções facilmente.

    Para mais informações sobre o uso da extensão, consulte a documentação da Extensão do VS Code.

    Aprofunde seu conhecimento

    Se quiser saber mais, você também pode implementar o Editor Visual ou usar o CMS para externalizar seu conteúdo.

    Perguntas Frequentes

    A opção nativa de i18n do Astro cuida dos prefixos de rota e redirecionamentos, mas não gerencia as mensagens, e uma ilha traz uma complexidade adicional por rodar Svelte em vez de Astro.

    • i18n integrado do Astro com dicionários manuais, junto com svelte-i18n dentro da ilha: duas fontes de conteúdo para manter e nenhuma tipagem compartilhada entre ambas.
    • Intlayer: uma camada única de conteúdo para ambos. O astro-intlayer cuida das páginas .astro e o svelte-intlayer das ilhas Svelte, lendo as mesmas declarações.

    Declarar um texto uma única vez e utilizá-lo tanto em uma página estática quanto em uma ilha interativa é o grande benefício de unificar a camada de conteúdo. Consulte por que Intlayer.

    Muito menos do que uma configuração baseada em namespaces, porque uma página nunca baixa um catálogo que não renderiza. As páginas Astro são renderizadas em tempo de build, portanto enviam HTML traduzido e nenhum dicionário; apenas as ilhas recebem dados. O compilador em tempo de build resolve as chamadas de conteúdo para as entradas exatas que o componente utiliza, e os dicionários dinâmicos dividem o restante por locale. Comparado às alternativas habituais, o Intlayer reduz o tamanho do bundle e da página em até 50%. Consulte otimização de bundle e o benchmark.

    Em grande parte, sim. Siga o guia de migração do Svelte I18n para migrar seu conteúdo. Você também pode migrar gradualmente: o plugin sync JSON mantém seus catálogos JSON existentes como fonte de verdade e gera dicionários Intlayer a partir deles, mantendo ambas as camadas sincronizadas enquanto você migra componentes um a um.

    Sim. O plugin sync JSON mantém seus arquivos /messages/{locale}/{namespace}.json como fonte de verdade e gera dicionários Intlayer a partir deles, em ambas as direções. O plugin sync PO faz o mesmo para catálogos gettext, e os arquivos por locale permitem dividir o conteúdo por idioma em vez de agrupar todos os locales em um único arquivo.

    Não. Execute npx intlayer extract e o Intlayer lê seus componentes, extrai as strings voltadas para o usuário e escreve um arquivo .content ao lado de cada um, para que você revise um diff em vez de copiar strings para um catálogo uma a uma. O passo 15 deste guia detalha esse processo.

    Para um fluxo de trabalho totalmente automatizado, o Intlayer Compiler faz o mesmo em tempo de build: ele analisa seu código JSX, TSX, Vue e Svelte a cada alteração, gera os dicionários e os mantém sincronizados via hot module replacement, dispensando completamente a manutenção manual de chaves.

    Dois limites são importantes considerar: o compilador opera por análise estática, de modo que strings criadas apenas em tempo de execução (como códigos de erro de API ou campos dinâmicos de CMS) ficam fora de alcance. Além disso, ele precisa distinguir texto visível de lógicas de aplicação como className="active" ou status codes, exigindo algumas anotações em bases de código extensas. O comando extract evita ambos mantendo você no controle.

    Cinco ferramentas, todas opcionais:

    • Extensão VS Code: navegue de uma chave useIntlayer diretamente para o arquivo de conteúdo que a declara, extraia conteúdo de um componente e execute build, fill, test, push e pull pela paleta de comandos ou pela aba dedicada do Intlayer.
    • Servidor LSP: a mesma inteligência em qualquer editor compatível com LSP, com ir para definição, localizar referências, pré-visualizações de valores traduzidos ao passar o mouse, autocompletar e alertas para chaves não declaradas. Também resolve chamadas de i18next, react-i18next, next-intl e use-intl, facilitando a migração.
    • Servidor MCP: expõe a documentação e a CLI do Intlayer para Cursor, VS Code, Claude Desktop, Claude Code e ChatGPT, permitindo que os assistentes respondam com base na documentação atualizada e executem comandos como intlayer fill.
    • Agent Skills: habilidades focadas como intlayer-config, intlayer-cli e intlayer-content, além de uma por framework, ensinando ao agente suas regras de roteamento e tipos de nós.
    • Plugin ESLint: a regra no-raw-text identifica strings hardcoded, com regras adicionais para chaves estáticas e conteúdo não utilizado.