Next.js-Integration

@lingo.dev/compiler integriert sich über einen asynchronen Konfigurations-Wrapper in Next.js App Router und unterstützt sowohl Webpack als auch Turbopack.

Einrichtung

1. Paket installieren

pnpm install @lingo.dev/compiler

2. Next.js konfigurieren

Aktualisieren Sie Ihre next.config.ts, um den asynchronen withLingo()-Wrapper zu verwenden:

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

const nextConfig: NextConfig = {
  // Your existing Next.js config
};

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

Warum asynchron? Der Wrapper lädt Plugins verzögert und löst die Konfiguration dynamisch auf. Dies hält Ihren Build schnell und ermöglicht das bedingte Laden von Plugins.

3. Provider hinzufügen

Umschließen Sie Ihre App mit LingoProvider in Ihrem Root-Layout:

// 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>
  );
}

Wichtig: Platzieren Sie LingoProvider innerhalb von <html>, aber umschließen Sie damit alle Inhalte. Es funktioniert sowohl mit Server- als auch mit Client-Komponenten.

React Server Components

Der Compiler unterstützt React Server Components (RSC) vollständig. Server-Komponenten werden zur Build-Zeit übersetzt, und die Übersetzungen werden in die Server-Ausgabe eingebettet.

// app/page.tsx (Server Component)
export default function Page() {
  return (
    <div>
      <h1>Welcome to our app</h1>
      <p>This is a server component—translated at build time</p>
    </div>
  );
}

Für übersetzten Text in Server-Komponenten wird kein clientseitiges JavaScript hinzugefügt.

Client-Komponenten

Verwenden Sie für Client-Komponenten die "use client"-Direktive:

"use client";

import { useLingoContext } from "@lingo.dev/compiler/react";

export function LanguageSwitcher() {
  const { locale, setLocale } = useLingoContext();

  return (
    <select value={locale} onChange={(e) => setLocale(e.target.value)}>
      <option value="en">English</option>
      <option value="es">Español</option>
      <option value="de">Deutsch</option>
    </select>
  );
}

Client-Komponenten erhalten optimierte Übersetzungs-Bundles. Es werden nur die Übersetzungen einbezogen, die in dieser Komponente verwendet werden.

Locale-Erkennung

Standardmäßig wird die Locale in einem Cookie (locale) gespeichert. Der Compiler übernimmt automatisch die Locale-Erkennung und -Persistierung.

Benutzerdefinierte Server-Locale-Erkennung

Für benutzerdefinierte Logik (Datenbank, Header, Subdomain) erstellen Sie .lingo/locale-resolver.server.ts:

// .lingo/locale-resolver.server.ts
import { headers } from "next/headers";

export async function getServerLocale(): Promise<string> {
  const headersList = await headers();
  const acceptLanguage = headersList.get("accept-language");

  // Parse accept-language header
  const locale = acceptLanguage?.split(",")[0]?.split("-")[0] || "en";

  return locale;
}

Diese Funktion wird auf dem Server für jede Anfrage aufgerufen. Sie sollte den Locale-Code zurückgeben (z. B. "en", "es").

Benutzerdefinierte Client-Locale-Persistierung

Für benutzerdefinierte clientseitige Logik (localStorage, URL-Parameter) erstellen Sie .lingo/locale-resolver.client.ts:

// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
  // Check URL parameter first
  const params = new URLSearchParams(window.location.search);
  const urlLocale = params.get("lang");
  if (urlLocale) return urlLocale;

  // Fall back to localStorage
  return localStorage.getItem("locale") || "en";
}

export function persistLocale(locale: string): void {
  localStorage.setItem("locale", locale);

  // Optionally update URL
  const url = new URL(window.location.href);
  url.searchParams.set("lang", locale);
  window.history.replaceState({}, "", url.toString());
}

Siehe Custom Locale Resolvers für weitere Details.

Middleware für Locale-Routing

Wenn Sie Locale-basiertes Routing wünschen (/en/about, /es/about), implementieren Sie Next.js-Middleware:

// middleware.ts
import { NextRequest, NextResponse } from "next/server";

const locales = ["en", "es", "de", "fr"];
const defaultLocale = "en";

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // Check if pathname already has a locale
  const pathnameHasLocale = locales.some(
    (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
  );

  if (pathnameHasLocale) return;

  // Get locale from cookie or accept-language header
  const localeCookie = request.cookies.get("locale")?.value;
  const acceptLanguage = request.headers.get("accept-language");
  const locale =
    localeCookie ||
    acceptLanguage?.split(",")[0]?.split("-")[0] ||
    defaultLocale;

  // Redirect to localized pathname
  request.nextUrl.pathname = `/${locale}${pathname}`;
  return NextResponse.redirect(request.nextUrl);
}

export const config = {
  matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};

Aktualisieren Sie Ihre Routen, um das dynamische Segment [locale] zu verwenden:

app/
  [locale]/
    page.tsx
    about/
      page.tsx
    layout.tsx

Build-Konfiguration

Development-Build

{
  dev: {
    usePseudotranslator: true, // Fast fake translations
  }
}

Führen Sie npm run dev aus, um den Development-Server mit sofortigen Pseudoübersetzungen zu starten.

Production-Build

{
  buildMode: "cache-only", // Use pre-generated translations
}

Führen Sie npm run build aus, um für Production zu builden. Keine API-Keys erforderlich – Übersetzungen stammen aus .lingo/metadata.json.

Best Practice: Generieren Sie echte Übersetzungen in CI, bevor Sie für Production builden. Siehe Build Modes für den empfohlenen Workflow.

Turbopack-Unterstützung

Der Compiler funktioniert sowohl mit Webpack als auch mit Turbopack (Next.js 15+).

Um Turbopack in der Entwicklung zu verwenden:

next dev --turbo

Der Compiler erkennt und konfiguriert automatisch den entsprechenden Bundler.

TypeScript

Der Compiler ist vollständig typisiert. Importieren Sie Typen aus @lingo.dev/compiler:

import type { LingoConfig } from "@lingo.dev/compiler";

const config: LingoConfig = {
  sourceRoot: "./app",
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
};

Häufige Probleme

"Cannot find module '@lingo.dev/compiler/react'" Stellen Sie sicher, dass Sie das Paket installiert haben: pnpm install @lingo.dev/compiler

HMR funktioniert nach Hinzufügen von LingoProvider nicht Stellen Sie sicher, dass LingoProvider korrekt in Ihrem Root-Layout platziert ist, nicht in einem verschachtelten Layout oder einer Seite.

Übersetzungen werden im Production-Build nicht angezeigt Überprüfen Sie, dass Sie buildMode: "cache-only" verwenden und dass .lingo/metadata.json Übersetzungen für alle Locales enthält.

"Missing translations for locale X" Führen Sie Ihren Dev-Server mit usePseudotranslator: false aus, um echte Übersetzungen zu generieren, oder führen Sie einen CI-Build aus, um .lingo/metadata.json zu befüllen.

Nächste Schritte