|
Dokumentation
Demo buchenPlattform
PlattformMCPCLIAPIWorkflows
Leitfäden
Changelog

Lokalisierung

  • Überblick
  • Translation API
  • Lokalisierung für Web-Apps
  • Lokalisierung für mobile Apps
  • iOS mit String Catalogs
  • Android mit strings.xml
  • E-Mail-Lokalisierung
  • Statische Inhalte (z. B. .md, .json)
  • Next.js mit Markdoc
  • Rails mit i18n

Workflows

  • Engine-Setup mit MCP
  • Jira-Triage
  • CI/CD

Next.js App Router-Lokalisierung mit Markdoc

Die Lingo.dev CLI übersetzt Markdoc-Dateien und JSON-Kataloge mit UI-Strings über eine konfigurierte Lokalisierungs-Engine. Markdoc ist ein Markdown-basiertes Authoring-Format mit typisierten, React-gestützten Custom Tags – ideal für Next.js App Router-Websites, die umfangreiche Inhalte mit interaktiven Komponenten verbinden.

Diese Anleitung zeigt Ihnen Schritt für Schritt, wie Sie eine Next.js App Router-Website vollständig lokalisieren: von der Konfiguration der CLI über die Organisation sprachspezifischer Inhalte und das Rendern von Markdoc in dynamischen Routen bis zur Automatisierung mit GitHub Actions.

Demo-Repository

Klonen oder forken Sie lingodotdev/markdoc-nextjs-localization-example, um direkt mitzumachen. Das Repository enthält eine funktionierende Next.js App Router-App mit Markdoc-Inhalten, einer Lingo.dev CLI-Konfiguration und einem GitHub Actions-Workflow.

So funktioniert die Lokalisierung mit Next.js + Markdoc#

Die meisten Next.js App Router-Websites unterteilen lokalisierte Inhalte in zwei Ebenen:

EbeneInhaltBeispieldatei
Umfangreiche InhalteMarketingseiten, Dokumentation, Blogbeiträgesrc/content/[locale]/pages/home.md
UI-StringsNavbar-Labels, CTAs, Button-Statussrc/content/[locale]/ui.json

Die Routen liegen unter src/app/[lang]/ und lesen zur Laufzeit die Dateien der passenden Sprache. Eine Middleware wählt anhand des Accept-Language-Headers des Browsers eine Standardsprache aus und leitet einfache Pfade wie / zu /en weiter – oder zur jeweils besten Übereinstimmung.

Der Bucket markdoc der CLI verarbeitet Markdoc-Dateien, ohne Frontmatter oder Custom Tags zu verändern, während der Bucket json den Katalog mit UI-Strings übernimmt. Beide übersetzen nur das Delta über Ihre Lokalisierungs-Engine und schreiben sprachspezifische Dateien direkt neben die Quelldateien.

Voraussetzungen#

1

Eine Lokalisierungs-Engine erstellen

Jeder CLI-Durchlauf schickt Inhalte durch eine Lokalisierungs-Engine – also die Konfiguration, die festlegt, welches LLM-Modell, Glossar, Markenstimme und welche Anweisungen gelten. Erstellen Sie sie im Lingo.dev dashboard und generieren Sie einen API-Schlüssel.

2

Node.js prüfen

Die CLI setzt Node.js 18 oder höher voraus:

bash
node -v
3

Ihr Next.js-Projekt einrichten

Ihr Projekt benötigt den App Router (src/app/) und ein Inhaltsverzeichnis pro Sprache. Das Demo-Repository verwendet src/content/[locale]/ mit zwei Unterordnern (pages/ und blog/) sowie einer Datei ui.json. Die Grundlagen zum Routing finden Sie unter Next.js internationalization.

Inhalte organisieren#

Teilen Sie Inhalte nach ihrer Funktion auf. Umfangreiche Seiten und Beiträge werden in Markdoc verfasst, kurze UI-Strings liegen in JSON, damit Komponenten sie direkt laden können.

text
src/content/
  en/                  # Source locale
    pages/home.md      # Long-form Markdoc
    blog/hello.md
    ui.json            # UI strings (navbar, CTAs, button states)
  es/                  # Target locales – generated by Lingo.dev
  fr/
  de/

Markdoc-Dateien unterstützen Frontmatter für seitenbezogene Metadaten wie Titel, Beschreibung, Datum und Autor sowie Custom Tags, die als React-Komponenten gerendert werden. Eine minimale Seite sieht so aus:

markdown
---
title: Author once in Markdoc, ship in every language.
description: An example Next.js App Router app that localizes Markdoc with Lingo.
---

{% inline-callout type="info" %}
This page is authored in Markdoc and translated by Lingo.dev.
{% /inline-callout %}

## Built from three pieces

Markdoc custom tags render as React components – even interactive ones.

Die CLI konfigurieren#

Erstellen Sie im Stammverzeichnis Ihres Projekts eine Datei i18n.json. Deklarieren Sie darin zwei Buckets – einen für Markdoc-Inhalte und einen für den UI-String-Katalog:

json
{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de"]
  },
  "buckets": {
    "markdoc": {
      "include": [
        "src/content/[locale]/pages/*.md",
        "src/content/[locale]/blog/*.md"
      ]
    },
    "json": {
      "include": ["src/content/[locale]/ui.json"]
    }
  }
}

Der Platzhalter [locale] wird jeweils zum konfigurierten Sprachcode aufgelöst. Mit source: "en" liest die CLI aus src/content/en/ und schreibt übersetzte Dateien nach src/content/es/, src/content/fr/ und src/content/de/.

Einzeldatei-Kataloge

Wenn Ihre UI-Strings in einer einzelnen mehrsprachigen JSON-Datei statt in separaten Dateien pro Sprache liegen, verwenden Sie den Bucket-Typ json-per-locale. Die vollständige Liste der Bucket-Typen finden Sie unter Static Content Localization.

Markdoc im App Router rendern#

Eine typische dynamische Route lädt ein Dokument und rendert den transformierten Baum. Das Demo-Repository stellt dafür einen kleinen Helper bereit:

ts
// src/lib/markdoc.ts
export async function loadDoc(
  locale: Locale,
  collection: "pages" | "blog",
  slug: string,
) {
  const raw = await fs.readFile(
    path.join(process.cwd(), "src/content", locale, collection, `${slug}.md`),
    "utf8",
  );
  const ast = Markdoc.parse(raw);
  const frontmatter = ast.attributes.frontmatter
    ? parseFrontmatter(ast.attributes.frontmatter)
    : {};
  const content = Markdoc.transform(ast, { ...schema, variables: { frontmatter } });
  return { frontmatter, content };
}

Die App Router-Seite ist ein schlanker Wrapper, der das Dokument mit sprachspezifischen UI-Strings kombiniert:

tsx
// src/app/[lang]/page.tsx
export default async function Home({ params }: PageProps<"/[lang]">) {
  const { lang } = await params;
  const doc = await loadDoc(lang, "pages", "home");
  const { home } = await getMessages(lang);

  return (
    <main>
      <h1>{doc.frontmatter.title}</h1>
      {renderMarkdoc(doc.content)}
    </main>
  );
}

Custom Tags in Markdoc (callout, bento, blog-hero usw.) werden in markdoc.schema.ts deklariert und mit React-Komponenten unter src/components/markdoc/ verknüpft. Die vollständige API finden Sie in den Markdoc schema docs.

Sprache in der Middleware erkennen#

Die Next.js-Middleware prüft die Anfrage, bevor eine Route gerendert wird. Verwenden Sie sie, um einfache Pfade anhand des Accept-Language-Headers zur am besten passenden Sprache weiterzuleiten:

ts
// src/middleware.ts
export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const hasLocale = locales.some(
    (locale) => pathname === `/${locale}` || pathname.startsWith(`/${locale}/`),
  );
  if (hasLocale) return;

  const locale = pickLocale(request); // parses Accept-Language
  const url = request.nextUrl.clone();
  url.pathname = `/${locale}${pathname === "/" ? "" : pathname}`;
  return NextResponse.redirect(url);
}

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

Besucher landen auf /en, /es, /fr oder /de, ohne das Präfix selbst eingeben zu müssen.

Lokal übersetzen#

Setzen Sie Ihren API-Schlüssel und führen Sie die CLI aus:

bash
export LINGO_API_KEY="your-api-key"
npx lingo.dev@latest run

Die CLI liest jede Datei, die zu Ihren Bucket-Mustern passt, identifiziert mithilfe der lockfile noch nicht übersetzte Einträge, übersetzt nur das Delta über Ihre Lokalisierungs-Engine und schreibt die Ergebnisse in das Verzeichnis der jeweiligen Zielsprache. Frontmatter-Schlüssel, Markdoc-Custom-Tags und JSON-Strukturen bleiben dabei unverändert – nur der übersetzbare Text ändert sich.

So legen Sie während der Entwicklung eine bestimmte Zielsprache fest:

bash
npx lingo.dev@latest run --target-locale es

Mit GitHub Actions automatisieren#

Fügen Sie unter .github/workflows/translate.yml eine Workflow-Datei hinzu, um bei jedem Push zu übersetzen:

Übersetzungen werden direkt in main committet – ohne Reibungsverluste und ideal für kleine Teams:

yaml
name: Translate
on:
  push:
    branches: [main]
permissions:
  contents: write
jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lingo.dev
        uses: lingodotdev/lingo.dev@main
        with:
          api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

Speichern Sie Ihren API-Schlüssel in Ihrem GitHub-Repository unter Settings > Secrets and variables > Actions als LINGODOTDEV_API_KEY.

Vor dem Deployment prüfen#

Verwenden Sie das Flag --frozen als Deployment-Gate, damit keine unübersetzten Inhalte in Produktion gehen. Die CLI endet mit einem Status ungleich null, wenn noch Einträge übersetzt werden müssen:

bash
npx lingo.dev@latest run --frozen

Fügen Sie dies vor Ihrem Next.js-Build als separaten CI-Schritt hinzu:

yaml
- name: Verify translations
  run: npx lingo.dev@latest run --frozen
- name: Build
  run: pnpm build

Nächste Schritte#

Static Content Localization
Markdown-, MDX-, JSON-, YAML- und weitere Bucket-Typen
Web-App-Lokalisierung
UI-String-Muster in gängigen Web-Frameworks
CI/CD-Workflows
Muster für GitHub Actions, GitLab CI und Bitbucket Pipelines
Glossare
Markennamen und Fachbegriffe vor Übersetzungen schützen

War diese Seite hilfreich?

Max PrilutskiyMax Prilutskiy·Aktualisiert vor 9 Tagen·5 Min. Lesezeit