Receba notificações sobre os próximos lançamentos de Intlayer
    Criação:2025-09-09Última atualização:2025-09-09

    Começando a Internacionalizar (i18n) com Intlayer e Tanstack Start

    Este guia demonstra como integrar o Intlayer para uma internacionalização perfeita em projetos Tanstack Start com roteamento sensível ao locale, suporte a TypeScript e práticas modernas de desenvolvimento.

    O que é o Intlayer?

    Intlayer é uma biblioteca inovadora e de código aberto para internacionalização (i18n) projetada para simplificar o suporte multilíngue em aplicações web modernas.

    Com o Intlayer, você pode:

    • Gerenciar traduções facilmente usando dicionários declarativos no nível do componente.
    • Localizar dinamicamente metadados, rotas e conteúdo.
    • Garantir suporte a TypeScript com tipos gerados automaticamente, melhorando o autocompletar e a detecção de erros.
    • Aproveitar recursos avançados, como detecção e troca dinâmica de locale.
    • Ativar roteamento sensível ao locale com o sistema de roteamento baseado em arquivos do Tanstack Start.

    Guia Passo a Passo para Configurar o Intlayer em uma Aplicação Tanstack Start

    Passo 1: Criar o Projeto

    Comece criando um novo projeto TanStack Start seguindo o guia Iniciar novo projeto no site do TanStack Start.

    Passo 2: Instalar os Pacotes do Intlayer

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

    npm install intlayer react-intlayernpm install vite-intlayer --save-dev
    • intlayer

    • intlayer

      O pacote principal que fornece ferramentas de internacionalização para gerenciamento de configuração, tradução, declaração de conteúdo, transpiração e comandos CLI.

    • react-intlayer O pacote que integra o Intlayer com aplicações React. Ele fornece provedores de contexto e hooks para internacionalização em React.

    • vite-intlayer Inclui o plugin Vite para integrar o Intlayer com o empacotador Vite, assim como middleware para detectar o locale preferido do usuário, gerenciar cookies e lidar com redirecionamento de URLs.

    Passo 3: Configuração do seu projeto

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

    intlayer.config.ts
    import type { IntlayerConfig } from "intlayer";import { Locales } from "intlayer";const config: IntlayerConfig = {  internationalization: {    defaultLocale: Locales.ENGLISH,    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],  },};export default config;

    Através deste arquivo de configuração, você pode configurar URLs localizadas, redirecionamento de middleware, nomes de cookies, a localização e extensão das suas declarações de conteúdo, desabilitar logs do Intlayer no console, e muito mais. Para uma lista completa dos parâmetros disponíveis, consulte a documentação de configuração.

    Passo 4: Integre o Intlayer na sua Configuração do Vite

    Adicione o plugin intlayer na sua configuração:

    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [reactRouter(), tsconfigPaths(), intlayer()],});

    O plugin intlayer() para Vite é usado para integrar o Intlayer com o Vite. Ele garante a construção dos arquivos de declaração de conteúdo e os monitora no modo de desenvolvimento. Define as variáveis de ambiente do Intlayer dentro da aplicação Vite. Além disso, fornece aliases para otimizar o desempenho.

    Passo 5: Crie Componentes de Layout

    Configure seu layout raiz e layouts específicos para cada localidade:

    Layout Raiz

    src/routes/{-$locale}/route.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes";export const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Passo 6: Declare Seu Conteúdo

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

    src/contents/page.content.ts
    import type { Dictionary } from "intlayer";import { t } from "intlayer";const appContent = {  content: {    links: {      about: t({        pt: "Sobre",        en: "About",        es: "Acerca de",        fr: "À propos",      }),      home: t({        pt: "Início",        en: "Home",        es: "Inicio",        fr: "Accueil",      }),    },    meta: {      description: t({        pt: "Este é um exemplo de uso do Intlayer com TanStack Router",        en: "This is an example of using Intlayer with TanStack Router",        es: "Este es un ejemplo de uso de Intlayer con TanStack Router",        fr: "Ceci est un exemple d'utilisation d'Intlayer avec TanStack Router",      }),    },    title: t({      pt: "Bem-vindo ao Intlayer + TanStack Router",      en: "Welcome to Intlayer + TanStack Router",      es: "Bienvenido a Intlayer + TanStack Router",      fr: "Bienvenue à Intlayer + TanStack Router",    }),  },  key: "app",} satisfies Dictionary;export default appContent;

    Suas declarações de conteúdo podem ser definidas em qualquer lugar da sua aplicação assim que forem incluídas no diretório contentDir (por padrão, ./app). E devem corresponder à extensão do arquivo de declaração de conteúdo (por padrão, .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}).

    Para mais detalhes, consulte a documentação de declaração de conteúdo.

    Passo 7: Crie Componentes e Hooks Sensíveis ao Locale

    Crie um componente LocalizedLink para navegação sensível ao locale:

    src/components/localized-link.tsx
    import type { FC } from "react";import { Link, type LinkComponentProps } from "@tanstack/react-router";import { useLocale } from "react-intlayer";export const LOCALE_ROUTE = "{-$locale}" as const;// Utilitário principalexport type RemoveLocaleParam<T> = T extends string  ? RemoveLocaleFromString<T>  : T;export type To = RemoveLocaleParam<LinkComponentProps["to"]>;type CollapseDoubleSlashes<S extends string> =  S extends `${infer H}//${infer T}` ? CollapseDoubleSlashes<`${H}/${T}`> : S;type LocalizedLinkProps = {  to?: To;} & Omit<LinkComponentProps, "to">;// Auxiliarestype RemoveAll<  S extends string,  Sub extends string,> = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<  RemoveAll<S, typeof LOCALE_ROUTE>>;export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {  const { locale } = useLocale();  return (    <Link      {...props}      params={{        locale,        ...(typeof props?.params === "object" ? props?.params : {}),      }}      to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]}    />  );};

    Este componente tem dois objetivos:

    • Remover o prefixo {-$locale} desnecessário da URL.
    • Injetar o parâmetro de locale na URL para garantir que o usuário seja redirecionado diretamente para a rota localizada.

    Então, podemos criar um hook useLocalizedNavigate para navegação programática:

    src/hooks/useLocalizedNavigate.tsx
    import { useLocale } from "react-intlayer";import { useNavigate } from "@tanstack/react-router";import { LOCALE_ROUTE } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";export const useLocalizedNavigate = () => {  const navigate = useNavigate();  const { locale } = useLocale();  type StripLocalePrefix<T extends string> = T extends    | `/${typeof LOCALE_ROUTE}`    | `/${typeof LOCALE_ROUTE}/`    ? "/"    : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`      ? `/${Rest}`      : never;  type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;  interface LocalizedNavigate {    (to: LocalizedTo): ReturnType<typeof navigate>;    (      opts: { to: LocalizedTo } & Record<string, unknown>    ): ReturnType<typeof navigate>;  }  const localizedNavigate: LocalizedNavigate = (args: any) => {    if (typeof args === "string") {      return navigate({ to: `/${LOCALE_ROUTE}${args}`, params: { locale } });    }    const { to, ...rest } = args;    const localedTo = `/${LOCALE_ROUTE}${to}` as any;    return navigate({ to: localedTo, params: { locale, ...rest } as any });  };  return localizedNavigate;};

    Passo 8: Utilize o Intlayer em Suas Páginas

    Acesse seus dicionários de conteúdo em toda a sua aplicação:

    Página Inicial Localizada

    src/routes/{-$locale}/index.tsx
    import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";import { useIntlayer } from "react-intlayer";import LocaleSwitcher from "@/components/locale-switcher";import { LocalizedLink } from "@/components/localized-link";import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = params;    const metaContent = getIntlayer("app", locale);    return {      meta: [        { title: metaContent.title },        { content: metaContent.meta.description, name: "description" },      ],    };  },});function RouteComponent() {  const content = useIntlayer("app");  const navigate = useLocalizedNavigate();  return (    <div>      <div>        {content.title}        <LocaleSwitcher />        <div>          <LocalizedLink to="/">{content.links.home}</LocalizedLink>          <LocalizedLink to="/about">{content.links.about}</LocalizedLink>        </div>        <div>          <button onClick={() => navigate({ to: "/" })}>            {content.links.home}          </button>          <button onClick={() => navigate({ to: "/about" })}>            {content.links.about}          </button>        </div>      </div>    </div>  );}

    Para saber mais sobre o hook useIntlayer, consulte a documentação.

    Passo 9: Criar um Componente de Troca de Idioma

    Crie um componente para permitir que os usuários mudem de idioma:

    src/components/locale-switcher.tsx
    import type { FC } from "react";import { useLocation } from "@tanstack/react-router";import { getHTMLTextDir, getLocaleName, getPathWithoutLocale } from "intlayer";import { setLocaleCookie, useIntlayer, useLocale } from "react-intlayer";import { LocalizedLink, To } from "./localized-link";export const LocaleSwitcher: FC = () => {  const { localeSwitcherLabel } = useIntlayer("locale-switcher");  const { pathname } = useLocation();  const { availableLocales, locale } = useLocale();  const pathWithoutLocale = getPathWithoutLocale(pathname);  return (    <ol>      {availableLocales.map((localeEl) => (        <li key={localeEl}>          <LocalizedLink            aria-current={localeEl === locale ? "page" : undefined}            aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeEl)}`}            onClick={() => setLocaleCookie(localeEl)}            params={{ locale: localeEl }}            to={pathWithoutLocale as To}          >            <span>              {/* Local - ex. FR */}              {localeItem}            </span>            <span>              {/* Idioma na sua própria Localização - ex. Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* Idioma na Localização atual - ex. Francés com a localização atual definida para Locales.SPANISH */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* Idioma em Inglês - ex. French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </LocalizedLink>        </li>      ))}    </ol>  );};

    Para saber mais sobre o hook useLocale, consulte a documentação.

    Passo 10: Adicionar Gerenciamento de Atributos HTML (Opcional)

    Crie um hook para gerenciar os atributos lang e dir do HTML:

    src/hooks/useI18nHTMLAttributes.tsx
    // src/hooks/useI18nHTMLAttributes.tsximport { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  useEffect(() => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  }, [locale]);};

    Então use-o no seu componente raiz:

    src/routes/{-$locale}/index.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes"; // importar o hookexport const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  useI18nHTMLAttributes(); // adicionar esta linha  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={locale ?? defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Passo 11: Adicionar middleware (Opcional)

    Você também pode usar o intlayerMiddleware para adicionar roteamento do lado do servidor à sua aplicação. Este plugin detectará automaticamente o idioma atual com base na URL e definirá o cookie de idioma apropriado. Se nenhum idioma for especificado, o plugin determinará o idioma mais adequado com base nas preferências de idioma do navegador do usuário. Se nenhum idioma for detectado, ele redirecionará para o idioma padrão.

    Observe que, para usar o intlayerMiddleware em produção, você precisa mover o pacote vite-intlayer de devDependencies para dependencies.

    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";import { intlayer, intlayerMiddleware } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [    tailwindcss(),    reactRouter(),    tsconfigPaths(),    intlayer(),    intlayerMiddleware(),  ],});

    Passo 12: Configurar o TypeScript (Opcional)

    O Intlayer utiliza a ampliação de módulos para aproveitar os benefícios do TypeScript e fortalecer sua base de código.

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

    tsconfig.json
    {  // ... suas configurações existentes  include: [    // ... seus includes existentes    ".intlayer/**/*.ts", // Incluir os tipos gerados automaticamente  ],}

    Configuração do Git

    É recomendado ignorar os arquivos gerados pelo Intlayer. Isso permite evitar que eles sejam comitados no seu repositório Git.

    Para isso, você pode adicionar as seguintes instruções ao seu arquivo .gitignore:

    .gitignore
    # Ignorar os arquivos gerados pelo Intlayer.intlayer

    Extensão VS Code

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

    Instalar no VS Code Marketplace

    Esta extensão oferece:

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

    Para mais detalhes sobre como usar a extensão, consulte a documentação da Extensão Intlayer para VS Code.


    Ir Além

    Para ir além, você pode implementar o editor visual ou externalizar seu conteúdo usando o CMS.


    Referências da Documentação

    Este guia abrangente fornece tudo o que você precisa para integrar o Intlayer com o Tanstack Start para uma aplicação totalmente internacionalizada com roteamento sensível ao idioma e suporte a TypeScript.

    Histórico da Documentação

    Versão Data Alterações
    5.8.1 2025-09-09 Adicionado para Tanstack Start
    Receba notificações sobre os próximos lançamentos de Intlayer