Integração com Next.js

Max PrilutskiyCEO e cofundadorAtualizado em: há 7 meses · 3 min de leitura

Alpha

O Compiler do Lingo.dev está em alpha. Ele é instável, não é recomendado para uso em produção e as APIs podem mudar entre versões.

O Compiler do Lingo.dev integra-se ao App Router do Next.js por meio do wrapper de configuração withLingo(), transformando seu pipeline de build para gerar bundles por idioma. Ele é compatível com React Server Components, Webpack e Turbopack sem exigir alterações no código dos seus componentes.

Pré-requisitos#

Requisitos

  • Next.js 14+ com App Router
  • Node.js 18+
  • @lingo.dev/compiler instalado

Instalação#

bash
pnpm install @lingo.dev/compiler

Configure o next.config.ts#

Envolva sua configuração do Next.js com withLingo. A função de configuração precisa ser async — isso é necessário porque withLingo faz uma inicialização assíncrona durante o build.

ts
// next.config.ts
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";

const nextConfig: NextConfig = {};

export default async function (): Promise<NextConfig> {
  return await withLingo(nextConfig, {
    sourceRoot: "./app",
    sourceLocale: "en",
    targetLocales: ["es", "de", "fr", "ja"],
    models: "lingo.dev",
    dev: {
      usePseudotranslator: true,
    },
  });
}

Config assíncrona obrigatória

A configuração precisa ser exportada como uma função async, e não como um objeto simples. Se você exportar um objeto simples, o Compiler não conseguirá inicializar e o build falhará. Consulte Solução de problemas para mais detalhes.

Adicione o LingoProvider#

Envolva o layout raiz com LingoProvider para habilitar o contexto de idioma em toda a árvore de componentes:

tsx
// app/layout.tsx
import { LingoProvider } from "@lingo.dev/compiler/react";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <LingoProvider>
      <html>
        <body>{children}</body>
      </html>
    </LingoProvider>
  );
}

LingoProvider cuida da resolução do idioma, da persistência e do carregamento dos dicionários. Ele funciona tanto com Server Components quanto com Client Components.

Server Components e Client Components#

O Compiler lida com os dois tipos de componente de forma transparente:

Tipo de componenteComo as traduções funcionam
React Server ComponentsAs traduções são resolvidas no momento da requisição, no servidor. Sem sobrecarga de JS no cliente.
Client Components ("use client")As traduções são incluídas no chunk do cliente. useLingoContext() disponível para alternância de idioma.
Componentes compartilhadosFuncionam em ambos os contextos. O Compiler detecta automaticamente o ambiente de renderização.
tsx
// app/page.tsx - Server Component (default)
export default function Home() {
  return <h1>Welcome to our app</h1>;
  // Renders translated text with zero client JS
}
tsx
// app/components/greeting.tsx - Client Component
"use client";

export function Greeting() {
  return <p>Hello, world</p>;
  // Translations included in client bundle
}

Compatibilidade com bundlers#

O wrapper withLingo() funciona com os dois bundlers compatíveis com o Next.js:

BundlerSuporteObservações
WebpackCompletoBundler padrão. Nenhuma configuração adicional é necessária.
TurbopackCompletoAtive com next dev --turbopack. O Compiler detecta o Turbopack automaticamente.

Configuração do sourceRoot#

A opção sourceRoot informa ao Compiler qual diretório contém seus componentes traduzíveis. Em projetos com Next.js App Router, normalmente esse diretório é ./app:

ts
{
  sourceRoot: "./app",
}

Se você tiver componentes fora de ./app (como um diretório compartilhado components/), defina sourceRoot como o diretório pai em comum:

ts
{
  sourceRoot: ".",
}

Um sourceRoot mais amplo significa que mais arquivos serão analisados. Em projetos grandes, mantenha-o o mais restrito possível para reduzir o tempo de build. Como alternativa, use useDirective: true e adicione 'use i18n' apenas aos arquivos que precisam de tradução. Consulte Estrutura do projeto para mais detalhes.

Próximos passos#