\n```\n\n> 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:\n\n> ```html\n> \"{content.image.value}\"\n> \"{content.image.toString()}\"\n> \"{String(content.image)}\"\n> ```\n\n> **Nota sobre a configuração de roteamento:**\n> A estrutura de diretórios que você usa depende da configuração `middleware.routing` no `intlayer.config.ts`:\n>\n> - **`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.\n> - **`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.\n> - **`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.\n\n\n\n\n\nCrie um custom element Lit. Chame `installIntlayer` no `connectedCallback` usando o atributo `locale` do servidor para inicializar o singleton de tradução no lado do cliente.\n\n```typescript fileName=\"src/components/lit/LitDemo.ts\"\nimport { LitElement, html } from \"lit\";\nimport { installIntlayer, useIntlayer, useLocale } from \"lit-intlayer\";\nimport { getLocalizedUrl, getLocaleName, type LocalesValues } from \"intlayer\";\n\nclass LitDemo extends LitElement {\n static properties = {\n locale: { type: String },\n };\n\n locale: LocalesValues = \"en\" as LocalesValues;\n\n private _content = useIntlayer(this, \"lit-demo\");\n private _localeCtrl = useLocale(this, {\n onLocaleChange: (newLocale: LocalesValues) => {\n window.location.href = getLocalizedUrl(\n window.location.pathname,\n newLocale\n );\n },\n });\n\n override connectedCallback() {\n super.connectedCallback();\n // Inicializa com a localidade detectada pelo servidor\n installIntlayer({ locale: this.locale as any });\n }\n\n override render() {\n const { greeting, description } = this._content;\n const {\n locale: currentLocale,\n availableLocales,\n setLocale,\n } = this._localeCtrl;\n\n return html`\n
\n

${greeting}

\n

${description}

\n \n
\n Mudar idioma:\n
\n ${availableLocales.map(\n (localeItem) => html`\n setLocale(localeItem)}\n >\n ${getLocaleName(localeItem)}\n ${getLocaleName(localeItem, currentLocale)}\n ${localeItem.toUpperCase()}\n \n `\n )}\n
\n
\n
\n `;\n }\n}\n\ncustomElements.define(\"lit-demo\", LitDemo);\n```\n\n> O atributo `locale` é passado da página Astro (detecção no servidor) e usado para inicializar o `installIntlayer` no `connectedCallback`, definindo o idioma inicial para todos os hooks `ReactiveController` dentro do elemento.\n\n> `useIntlayer` é registrado como um `ReactiveController`. Ele solicita automaticamente uma nova renderização do elemento quando o idioma muda, portanto, nenhuma lógica de inscrição adicional é necessária.\n\n
\n\n\n\nA funcionalidade de troca de idioma está integrada diretamente no método `render()` do custom element Lit (veja o passo 6 acima). Ela usa o `useLocale` do `lit-intlayer` e navega para a URL localizada quando um usuário seleciona um novo idioma:\n\n```typescript fileName=\"src/components/lit/LitDemo.ts\"\n// Dentro da classe LitElement, após a configuração do useLocale no passo 6:\n\nprivate _localeCtrl = useLocale(this, {\n onLocaleChange: (newLocale: LocalesValues) => {\n // Navega para a URL localizada ao mudar de idioma\n window.location.href = getLocalizedUrl(window.location.pathname, newLocale);\n },\n});\n\noverride render() {\n const { locale: currentLocale, availableLocales, setLocale } = this._localeCtrl;\n\n return html`\n
\n Mudar idioma:\n
\n ${availableLocales.map(\n (localeItem) => html`\n setLocale(localeItem)}\n >\n ${getLocaleName(localeItem)}\n ${getLocaleName(localeItem, currentLocale)}\n ${localeItem.toUpperCase()}\n \n `\n )}\n
\n
\n `;\n}\n```\n\n> **Nota sobre a reatividade do Lit:**\n> `useLocale` retorna um `ReactiveController`. Quando o `setLocale` é chamado, o controlador solicita automaticamente uma nova renderização, atualizando o estado do botão ativo sem a necessidade de manipulação manual do DOM.\n\n> **Nota sobre persistência:**\n> 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.\n\n
\n\n\n\nO Intlayer oferece utilitários para criar dinamicamente o seu sitemap localizado e os arquivos robots.txt.\n\n#### Sitemap\n\nO 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.\n\n> 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.\n\nCrie `src/pages/sitemap.xml.ts` para gerar um sitemap que inclua todas as suas rotas localizadas.\n\n```typescript fileName=\"src/pages/sitemap.xml.ts\"\nimport type { APIRoute } from \"astro\";\nimport { generateSitemap, type SitemapUrlEntry } from \"intlayer\";\n\nconst pathList: SitemapUrlEntry[] = [\n { path: \"/\", changefreq: \"daily\", priority: 1.0 },\n { path: \"/about\", changefreq: \"monthly\", priority: 0.7 },\n];\n\nconst SITE_URL = import.meta.env.SITE ?? \"http://localhost:4321\";\n\nexport const GET: APIRoute = async ({ site }) => {\n const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });\n\n return new Response(xmlOutput, {\n headers: { \"Content-Type\": \"application/xml\" },\n });\n};\n```\n\n#### Robots.txt\n\nCrie `src/pages/robots.txt.ts` para controlar o rastreamento dos motores de busca.\n\n```typescript fileName=\"src/pages/robots.txt.ts\"\nimport type { APIRoute } from \"astro\";\nimport { getMultilingualUrls } from \"intlayer\";\n\nconst getAllMultilingualUrls = (urls: string[]) =>\n urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);\n\nconst disallowedPaths = getAllMultilingualUrls([\"/admin\", \"/private\"]);\n\nexport const GET: APIRoute = ({ site }) => {\n const robotsTxt = [\n \"User-agent: *\",\n \"Allow: /\",\n ...disallowedPaths.map((path) => `Disallow: ${path}`),\n \"\",\n `Sitemap: ${new URL(\"/sitemap.xml\", site).href}`,\n ].join(\"\\n\");\n\n return new Response(robotsTxt, {\n headers: { \"Content-Type\": \"text/plain\" },\n });\n};\n```\n\n\n\n\n\nSe você tiver uma base de código existente, transformar milhares de arquivos pode ser demorado.\n\nPara facilitar esse processo, o Intlayer propõe um [compilador](/pt/doc/compiler) / [extrator](/pt/doc/concept/cli/extract) para transformar seus componentes e extrair o conteúdo.\n\nPara configurá-lo, você pode adicionar uma seção `compiler` no seu arquivo `intlayer.config.ts`:\n\n```typescript fileName=\"intlayer.config.ts\" codeFormat={[\"typescript\", \"esm\", \"commonjs\"]}\nimport { type IntlayerConfig } from \"intlayer\";\n\nconst config: IntlayerConfig = {\n // ... Resto da sua configuração\n compiler: {\n /**\n * Indica se o compilador deve ser ativado.\n */\n enabled: true,\n\n /**\n * Define o caminho dos arquivos de saída\n */\n output: ({ fileName, extension }) => `./${fileName}${extension}`,\n\n /**\n * 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.\n */\n saveComponents: false,\n\n /**\n * Prefixo da chave do dicionário\n */\n dictionaryKeyPrefix: \"\",\n },\n};\n\nexport default config;\n```\n\n\n \n\nExecute o extrator para transformar seus componentes e extrair o conteúdo\n\n```bash packageManager=\"npm\"\nnpx intlayer extract\n```\n\n```bash packageManager=\"pnpm\"\npnpm intlayer extract\n```\n\n```bash packageManager=\"yarn\"\nyarn intlayer extract\n```\n\n```bash packageManager=\"bun\"\nbun x intlayer extract\n```\n\n \n \n\nAtualize seu `vite.config.ts` para incluir o plugin `intlayerCompiler`:\n\n```ts fileName=\"vite.config.ts\"\nimport { defineConfig } from \"vite\";\nimport { intlayer, intlayerCompiler } from \"vite-intlayer\";\n\nexport default defineConfig({\n plugins: [\n intlayer(),\n intlayerCompiler(), // Adiciona o plugin do compilador\n ],\n});\n```\n\n```bash packageManager=\"npm\"\nnpm run build # Ou npm run dev\n```\n\n```bash packageManager=\"pnpm\"\npnpm run build # Or pnpm run dev\n```\n\n```bash packageManager=\"yarn\"\nyarn build # Or yarn dev\n```\n\n```bash packageManager=\"bun\"\nbun run build # Or bun run dev\n```\n\n \n\n\n---\n\n\n\n\n\n### Configuração do TypeScript\n\nO Intlayer usa o aumento de módulos (module augmentation) para aproveitar o TypeScript, tornando sua base de código mais robusta. Se você usar a sintaxe de decoradores, certifique-se de habilitar `experimentalDecorators` nas suas opções de compilador.\n\n![Preenchimento automático](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)\n\n![Erro de tradução](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)\n\nCertifique-se de que sua configuração do TypeScript inclua os tipos gerados automaticamente.\n\n```json5 fileName=\"tsconfig.json\"\n{\n compilerOptions: {\n // ...\n experimentalDecorators: true,\n useDefineForClassFields: false, // Necessário para suporte a decoradores no Lit\n },\n \"include\": [\n // ... sua configuração existente do TypeScript\n \".intlayer/**/*.ts\", // Incluir tipos gerados automaticamente\n ],\n}\n```\n\n### Configuração do Git\n\nRecomenda-se ignorar os arquivos gerados pelo Intlayer. Isso evita committá-los no seu repositório Git.\n\nPara fazer isso, adicione as seguintes instruções ao seu arquivo `.gitignore`:\n\n```bash\n# Ignorar os arquivos gerados pelo Intlayer\n.intlayer\n```\n\n### Extensão do VS Code\n\nPara melhorar sua experiência de desenvolvimento com o Intlayer, você pode instalar a **extensão oficial do Intlayer para VS Code**.\n\n[Instalação pelo VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)\n\nEsta extensão fornece:\n\n- **Preenchimento automático** para chaves de tradução.\n- **Detecção de erros em tempo real** para traduções ausentes.\n- **Visualização inline** do conteúdo traduzido.\n- **Ações rápidas** para criar e atualizar traduções facilmente.\n\nPara mais informações sobre o uso da extensão, consulte a [documentação da Extensão do VS Code](https://intlayer.org/doc/vs-code-extension).\n\n---\n\n### Aprofunde seu conhecimento\n\nSe quiser saber mais, você também pode implementar o [Editor Visual](/pt/doc/concept/editor) ou usar o [CMS](/pt/doc/concept/cms) para externalizar seu conteúdo.\n","description":"Sem mais i18next. O guia 2026 para criar uma aplicação Astro + Lit multilíngue (i18n). Traduza com agentes de IA e otimize o tamanho do bundle, SEO e desempenho.","url":"https://intlayer.org/pt/doc/environment/astro/lit","datePublished":"2026-04-24","dateModified":"2026-05-31","version":"8.9.0","keywords":"internacionalização, documentação, Intlayer, Astro, Lit, Web Components, i18n, JavaScript","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Desenvolvedores, Gerentes de Conteúdo"}}
    Autor:
    Criação:2026-04-24Última atualização:2026-05-31

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

    Í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 habilidades do agente, 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 + Lit

    ide.intlayer.org

    Confira o modelo da aplicação no GitHub.

    1. Instalar Dependências

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

      bash
      npm install intlayer astro-intlayer lit lit-intlayer @astrojs/litnpx intlayer init
      • 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.

      • lit Pacote principal do Lit para criar Web Components rápidos e leves.

      • lit-intlayer Pacote para integrar o Intlayer em aplicações Lit. Ele fornece hooks baseados em ReactiveController (useIntlayer, useLocale, etc.) que instruem automaticamente o LitElement a renderizar novamente quando o idioma muda.

      • @astrojs/lit Integração oficial do Astro que permite o uso de custom elements Lit dentro de páginas Astro.

    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 Lit à sua configuração do Astro.

      astro.config.ts
      // @ts-checkimport { intlayer } from "astro-intlayer";import lit from "@astrojs/lit";import { defineConfig } from "astro/config";// https://astro.build/configexport default defineConfig({  integrations: [intlayer(), lit()],});
      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 lit() permite o uso de custom elements Lit dentro de páginas Astro.
    4. Declarar seu conteúdo

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

      src/components/lit/app.content.ts
      import { t, type Dictionary } from "intlayer";const litDemoContent = {  key: "lit-demo",  content: {    greeting: t({      en: "Hello World",      fr: "Bonjour le monde",      es: "Hola mundo",      pt: "Olá Mundo",    }),    description: t({      en: "Welcome to my multilingual Astro + Lit site.",      fr: "Bienvenue sur mon site Astro + Lit multilingue.",      es: "Bienvenido a mi sitio Astro + Lit multilingüe.",      pt: "Bem-vindo ao meu site Astro + Lit multilíngue.",    }),  },} satisfies Dictionary;export default litDemoContent;
      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. Os custom elements Lit são importados via um <script> no cliente e colocados no corpo da página.

      src/pages/[...locale]/index.astro
      ---import {  getIntlayer,  getLocaleFromPath,  getLocalizedUrl,  getHTMLTextDir,  getPrefix,  localeMap,  defaultLocale,  type LocalesValues,} from "intlayer";export const getStaticPaths = () => {  return localeMap(({ locale }) => ({    params: { locale: getPrefix(locale).localePrefix },  }));};const locale = getLocaleFromPath(Astro.url.pathname) as LocalesValues;const { greeting } = getIntlayer("lit-demo", 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>{greeting}</title>    <!-- Link Canônico -->    <link      rel="canonical"      href={new URL(getLocalizedUrl(Astro.url.pathname, locale), Astro.site)}    />    <!-- Links Hreflang -->    {      localeMap(({ locale: mapLocale }) => (        <link          rel="alternate"          hreflang={mapLocale}          href={new URL(            getLocalizedUrl(Astro.url.pathname, mapLocale),            Astro.site          )}        />      ))    }    <link      rel="alternate"      hreflang="x-default"      href={new URL(        getLocalizedUrl(Astro.url.pathname, defaultLocale),        Astro.site      )}    />  </head>  <body>    <!-- Custom element Lit - recebe a localidade detectada pelo servidor como uma propriedade -->    <lit-demo locale={locale}></lit-demo>  </body></html><script>  import "../../components/lit/LitDemo";</script>
      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:
      html
      <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 Custom Element de Lit

      Crie um custom element Lit. Chame installIntlayer no connectedCallback usando o atributo locale do servidor para inicializar o singleton de tradução no lado do cliente.

      src/components/lit/LitDemo.ts
      import { LitElement, html } from "lit";import { installIntlayer, useIntlayer, useLocale } from "lit-intlayer";import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";class LitDemo extends LitElement {  static properties = {    locale: { type: String },  };  locale: LocalesValues = "en" as LocalesValues;  private _content = useIntlayer(this, "lit-demo");  private _localeCtrl = useLocale(this, {    onLocaleChange: (newLocale: LocalesValues) => {      window.location.href = getLocalizedUrl(        window.location.pathname,        newLocale      );    },  });  override connectedCallback() {    super.connectedCallback();    // Inicializa com a localidade detectada pelo servidor    installIntlayer({ locale: this.locale as any });  }  override render() {    const { greeting, description } = this._content;    const {      locale: currentLocale,      availableLocales,      setLocale,    } = this._localeCtrl;    return html`      <div>        <h1>${greeting}</h1>        <p>${description}</p>        <!-- Seletor de idioma renderizado dentro do LitElement -->        <div class="locale-switcher">          <span class="switcher-label">Mudar idioma:</span>          <div class="locale-buttons">            ${availableLocales.map(              (localeItem) => html`                <button                  class="locale-btn ${localeItem === currentLocale                    ? "active"                    : ""}"                  ?disabled=${localeItem === currentLocale}                  @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>              `            )}          </div>        </div>      </div>    `;  }}customElements.define("lit-demo", LitDemo);
      O atributo locale é passado da página Astro (detecção no servidor) e usado para inicializar o installIntlayer no connectedCallback, definindo o idioma inicial para todos os hooks ReactiveController dentro do elemento.
      useIntlayer é registrado como um ReactiveController. Ele solicita automaticamente uma nova renderização do elemento quando o idioma muda, portanto, nenhuma lógica de inscrição adicional é necessária.
    7. Adicionar um Seletor de Idioma

      A funcionalidade de troca de idioma está integrada diretamente no método render() do custom element Lit (veja o passo 6 acima). Ela usa o useLocale do lit-intlayer e navega para a URL localizada quando um usuário seleciona um novo idioma:

      src/components/lit/LitDemo.ts
      // Dentro da classe LitElement, após a configuração do useLocale no passo 6:private _localeCtrl = useLocale(this, {  onLocaleChange: (newLocale: LocalesValues) => {    // Navega para a URL localizada ao mudar de idioma    window.location.href = getLocalizedUrl(window.location.pathname, newLocale);  },});override render() {  const { locale: currentLocale, availableLocales, setLocale } = this._localeCtrl;  return html`    <div class="locale-switcher">      <span class="switcher-label">Mudar idioma:</span>      <div class="locale-buttons">        ${availableLocales.map(          (localeItem) => html`            <button              class="locale-btn ${localeItem === currentLocale ? "active" : ""}"              ?disabled=${localeItem === currentLocale}              @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>          `        )}      </div>    </div>  `;}

      Nota sobre a reatividade do Lit: useLocale retorna um ReactiveController. Quando o setLocale é chamado, o controlador solicita automaticamente uma nova renderização, atualizando o estado do botão ativo sem a necessidade de manipulação manual do DOM.

      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

    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. Se você usar a sintaxe de decoradores, certifique-se de habilitar experimentalDecorators nas suas opções de compilador.

    Preenchimento automático

    Erro de tradução

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

    tsconfig.json
    {  compilerOptions: {    // ...    experimentalDecorators: true,    useDefineForClassFields: false, // Necessário para suporte a decoradores no Lit  },  "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.