Communitygithub.com

mwasobaddy/skills

Architekt und implementiere Internationalisierung für Next.js App Router Anwendungen – Ordnerstruktur, sprachpräfix-basiertes Routing, typisierte Nachrichtendateien, ICU-Plurale und lokalisierte SEO mit hreflang.

Was ist skills?

Diese Fähigkeit bietet strukturierte Anleitungen zur Internationalisierung (i18n) von Next.js-Anwendungen, die den App Router nutzen. Sie hilft Entwicklern, die richtige Bibliothek (bevorzugt next-intl) auszuwählen, eine kanonische Ordnerstruktur mit einem `[locale]`-Segment zu erstellen und alle Aspekte des mehrsprachigen Routings, der Nachrichtenverwaltung und der SEO zu konfigurieren. Die Anleitung behandelt sowohl die Neueinrichtung als auch die Nachrüstung bestehender Apps, einschließlich der Migration von URLs, der Vermeidung häufiger Fallstricke (wie der Verwendung veralteter APIs wie `setRequestLocale` oder der Konkatenation von übersetzten Strings). Unterstützt werden die Plattformen next-intl, Lingui und next-i18next, wobei der Fokus auf dem App Router liegt. Die Fähigkeit enthält Referenzen zu detaillierten Setup-Anleitungen und Skripten zur Analyse unübersetzter Strings.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mwasobaddy/skills/tree/HEAD/nextjs-i18n

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Next.js i18n

Strukturelle Anleitung, um eine Next.js-App in mehrere Sprachen zu bringen: wie die Ordnerstruktur sein muss, was kaputt geht, wenn sie falsch ist, und was zu vermeiden ist.

Bibliothek zuerst auswählen

Standardmäßig next-intl für alles Neue mit dem App Router verwenden. Es benötigt kein Build-Plugin, keinen Makro-Schritt und kein manuelles Verwalten von sprachspezifischen Instanzen; Nachrichten sind einfaches JSON, das anhand der Quellsprache typisiert wird.

BibliothekWann verwendenKosten
next-intl (Standard)Neue App Router Arbeit, jede TeamgrößeKeine – einfaches JSON, kein Code-Generator
@lingui/reactWenn Du eine Compile-Zeit-Extraktion und eine minimale Laufzeitumgebung möchtest, oder eine einzige i18n-Schicht für React/Vue/AstroSWC- oder Babel-Makro-Plugin, genau festgelegt
next-i18nextDas Team kennt bereits i18next, oder Du migrierst Pages Router CodePro-Anfrage-Instanz, getT/useT-Aufteilung
Next.js eingebautes i18nNur Pages Router. Niemals App RouterNicht anwendbar

Die Next.js-Konfiguration i18n: { locales, defaultLocale } ist nur für den Pages Router. Im App Router tut sie nichts – Sprach-Routing bedeutet dort ein [locale]-Segment plus einen Proxy. Lass den Agenten nicht das eingebaute i18n für ein App Router Projekt „aktivieren".

Vollständiger Vergleich, einschließlich Bundle-Kosten und bibliotheksspezifischer Trade-offs: references/library-comparison.md.

Kanonische Architektur

Halte statische Wörterbücher außerhalb von src/, damit Bündelung und Importpfade offensichtlich bleiben, und halte die gesamte Sprach-Maschinerie in einem Ordner.

messages/                      # reine statische Wörterbücher – außerhalb von /src halten
├── en.json                     # Quelle der Wahrheit; jedes andere Gebietsschema spiegelt es
├── de.json
└── ja.json
src/
├── i18n/
│   ├── routing.ts              # defineRouting: Gebietsschemata + defaultLocale
│   ├── request.ts              # getRequestConfig: Gebietsschema auflösen, Nachrichten laden
│   └── navigation.ts           # createNavigation: sprachbewusster Link/Redirect
├── proxy.ts                    # Gebietsschema-Erkennung + Umleitung (Next 16; war middleware.ts)
└── app/
    ├── [locale]/               # umschließt die gesamte lokalisierte App
    │   ├── layout.tsx          # Gebietsschema validieren, <html lang>, generateStaticParams
    │   └── page.tsx
    └── not-found.tsx           # globale 404 lebt AUSSERHALB [locale]

Regeln, die diese Form zum Funktionieren bringen:

  • [locale] ist ein dynamisches Root-Segment. Alles Lokalisierte lebt darunter. Root-Level Routen (not-found.tsx, error.tsx, api/) bleiben außerhalb und dürfen keine i18n-Hooks bedingungslos aufrufen, sonst stürzen sie zur Laufzeit ab.
  • Eine Quellsprache. messages/en.json ist die Master-Datei. Jede andere Datei muss ihre Form exakt spiegeln.
  • Das gesamte Gebietsschema-Wissen in src/i18n/. Komponenten importieren Link aus @/i18n/navigation, niemals aus next/link. Ein Ort, um eine Sprache hinzuzufügen.

Einrichtung (Neuanlage)

In dieser Reihenfolge ausführen. Die Reihenfolge ist wichtig – proxy.ts hängt von routing.ts ab, und das Layout hängt von request.ts ab.

  1. Installiere next-intl, umschließe next.config.ts mit createNextIntlPlugin().
  2. Erstelle src/i18n/routing.ts mit defineRouting.
  3. Erstelle src/proxy.ts mit dem Export von createMiddleware(routing) plus dem Standard-Matcher.
  4. Erstelle src/i18n/request.ts mit getRequestConfig, das das Gebietsschema auflöst.
  5. Verschiebe app/** unter app/[locale]/**; füge generateStaticParams hinzu und validiere den Parameter.
  6. Erstelle src/i18n/navigation.ts mit createNavigation(routing).
  7. Erstelle messages/en.json und ersetze hartcodierte Strings durch useTranslations.
  8. Setze <html lang> und füge lokalisierte Metadaten + hreflang hinzu.

Exakte Dateiinhalte für jeden Schritt: references/next-intl-setup.md.

Fallstricke

Lies diesen Abschnitt, bevor Du i18n-Code schreibst. Dies sind die Fehler, die Stunden kosten.

  • setRequestLocale ist veraltet. Auf Next.js 16.3+ lies das Gebietsschema mit next/root-params innerhalb von getRequestConfig. Die meisten Anleitungen, Tutorials und LLM-Trainingsdaten lehren immer noch setRequestLocale(params.locale). Es funktioniert noch und ist als abwärtskompatibel dokumentiert – aber es ist die alte API. Verwende es nur auf Next < 16.3. generateStaticParams ist trotzdem erforderlich.
  • params ist ein Promise auf Next 15+. const {locale} = await params. Behandle params.locale als Typfehler, nicht als Laufzeitfehler.
  • Validiere das Gebietsschema oder unbekannte Werte werden gerendert. Verwende hasLocale(routing.locales, locale) und notFound(). Ohne dies rendert /xx/about Deine englische Seite unter einer gefälschten URL.
  • proxy.ts, nicht middleware.ts, auf Next 16. middleware.ts ist veraltet. Der Proxy läuft nur auf Node.js – die Edge-Laufzeit wird nicht unterstützt. Lingui und next-i18next bewerben Edge-sichere Proxies; wenn Du Edge brauchst, hast Du einen echten Kompromiss, keinen Freifahrtschein.
  • Übersetzte Strings niemals verketten. "Du hast " + count + " Artikel" ist ungrammatisch im Japanischen und Arabischen. Verwende ICU: "{count, plural, =1 {Ein Artikel} other {# Artikel}}".
  • Niemals mit + oder Template-Literalen innerhalb einer Nachricht interpolieren. Verwende benannte Platzhalter – {name} – damit die Wortreihenfolge geändert werden kann.
  • Daten und Zahlen verursachen Hydratationskonflikte. new Date() auf dem Server und im Browser unterscheiden sich um Zeitzone und Uhrzeit. Setze timeZone in getRequestConfig, oder rendere clientseitig für relative Zeiten. Symptom: „Text content does not match server-rendered HTML".
  • Formatierung ist gebietsschemaabhängig. toLocaleString() ohne explizites Gebietsschema formatiert nach Laufzeit-Gebietsschema, nicht nach angefordertem Gebietsschema. Verwende useFormatter() / getFormatter().
  • getRequestConfig läuft pro Anfrage und wird von React zwischengespeichert. Setze keinen anfrageabhängigen Status (Warenkorb, Benutzereinstellungen) dort hinein. Nur gebietsschemaabhängige Konfiguration.
  • Server Actions und Route Handler haben keine Root-Parameter. await locale() funktioniert in Server Components nur. Gib das Gebietsschema explizit als Argument in Actions und Handlern weiter.

Nachrüsten einer bestehenden App

Behandle dies als eine Migration mit URL-Auswirkungen, nicht als eine Konfigurationsänderung. Jede bestehende URL ändert ihre Form, wenn Du ein [locale]-Präfix hinzufügst.

Plane in dieser Reihenfolge:

  1. Strings inventarisieren – führe scripts/find-untranslated.sh aus, um hartcodierte JSX-Texte zu finden.
  2. Wähle die Routing-Strategie vor dem Codieren. Immer mit Sprachpräfix (/en/about, /de/about) ist die Standardeinstellung; es ist eindeutig und hreflang-sauber. localePrefix: 'as-needed' bedient das Standardgebietsschema unter dem bloßen Pfad – bessere URLs, schwächeres SEO-Signal. Entscheide jetzt; später zu wechseln ist eine vollständige Neumigration.
  3. Baue das Routing auf, bevor Du Komponenten anfasst. Bringe proxy.ts + [locale] mit nur englischen Nachrichten zum Laufen.
  4. Verschiebe Routen unter [locale]/ – dies ist ein großer mechanischer git mv. Führe es in einem Commit aus, damit git log --follow nützlich bleibt.
  5. Ersetze Strings Namespace für Namespace, nicht Datei für Datei. Übersetze einen Namespace vollständig, damit die Schlüsselform bewiesen ist, bevor sie sich vervielfacht.
  6. Füge Weiterleitungen für jede URL hinzu, die sich geändert hat. /about → /en/about (oder 307 zum erkannten Gebietsschema). Ohne dies verlierst Du alle bestehenden Rankings. Nicht verhandelbar.
  7. Füge hreflang + lokalisierte Metadaten erst hinzu, nachdem jedes Gebietsschema die Route hat, sonst gibst Du Alternativen aus, die auf 404er zeigen.

Vollständige Migrationssequenz mit Weiterleitungs- und Rollback-Notizen: references/migration.md.

Was zu vermeiden ist

  • Lege messages/ nicht in src/ ab. Server-only Wörterbücher im Quellbaum verschwimmen, was zum Client geht.
  • Importiere Link nicht aus next/link in lokalisierten Routen. Es verliert das Sprachpräfix und verlinkt still auf die falsche Sprache.
  • Schreibe Sprachpräfixe nicht von Hand in hrefs (href={/${locale}/about}). Verwende Link aus @/i18n/navigation, das Präfix-, as-needed- und Domain-Routing handhabt.
  • Verwende keinen flachen Schlüssel-Namespace. Gruppiere nach Funktion/Seite. Flache Schlüssel kollidieren und sind nicht durchsuchbar.
  • Übersetze nicht automatisch zur Build-Zeit als Quelle der Wahrheit. Maschinenausgabe ist ein Entwurf; sie ungeprüft zu committen macht Fehler dauerhaft und unauffindbar.
  • Füge kein Gebietsschema zu routing.locales hinzu und nenne es erledigt. Ohne eine übersetzte messages/xx.json rendert jede Seite Schlüssel oder fällt still zurück.
  • Mische keine Routing-Strategien. as-needed plus ein hreflang, das auf Präfix-URLs zeigt, ist ein selbst zugefügter SEO-Bug.

Referenzen

Lies diese bei Bedarf, nicht im Voraus:

  • references/library-comparison.md – Auswahl zwischen next-intl, Lingui, next-i18next; Bundle-Kosten, Migrationsauslöser, bibliotheksspezifische Einrichtungsstruktur.
  • references/next-intl-setup.md – jede Datei in der kanonischen Einrichtung, kopierfertig.
  • references/messages-and-keys.md – Namespace-Struktur, Schlüsselbenennung, ICU-Syntax, Datums-/Zahlen-/Listenformatierung, typisierte Nachrichten.
  • references/seo.md – hreflang, <html lang>, lokalisiertes generateMetadata, kanonisch, Sitemap-Alternativen, Sprachwechsler-SEO-Regeln.
  • references/migration.md – Nachrüsten einer bestehenden App, Weiterleitungen, Rollback.

Skripte

  • scripts/find-untranslated.sh – erkennt wahrscheinlich hartcodierte benutzerorientierte Strings in einem Projekt, damit Du den Arbeitsumfang vor dem Start einschätzen kannst. Führe es als Schritt 1 einer Nachrüstung aus.
  • scripts/run-trigger-eval.sh – misst, ob die description dieser Fähigkeit bei den richtigen Prompts ausgelöst wird. Verwende es, wenn Du die Beschreibung änderst.

Testen der Beschreibung

Die description ist das Einzige, was der Agent sieht, bevor er entscheidet, diese Fähigkeit zu laden. Wenn sie nicht ausgelöst wird, ist nichts darunter wichtig.

bash scripts/run-trigger-eval.sh --dry-run          # Zeige den Plan, keine API-Aufrufe
bash scripts/run-trigger-eval.sh --split train     # 12 Abfragen x 3 Durchläufe
bash scripts/run-trigger-eval.sh --split validation --out report.json

Abfragesatz: evals/trigger-queries.json – 12 sollen ausgelöst werden, 8 sollen nicht ausgelöst werden, aufgeteilt 60/40 in einen festen Trainings- und Validierungssatz.

Beim Bearbeiten der Beschreibung:

  • Behebe Fehler mit dem Trainings-Satz. Berühre den Validierungssatz nur einmal am Ende, um zu prüfen, ob die Änderung verallgemeinert – wenn das Training besser wird und die Validierung schlechter, hast Du überangepasst.
  • Soll-ausgelöst-Fehler bedeuten, dass die Beschreibung zu eng ist: Füge das Konzept hinzu, das die Abfrage repräsentiert, niemals die Schlüsselwörter der Abfrage.
  • Soll-nicht-ausgelöst-Fehler bedeuten, dass sie zu breit ist: Sage, was die Fähigkeit nicht abdeckt.
  • Führe vor dem Bearbeiten erneut aus. Das Auslösen ist nicht deterministisch, und ein Durchlauf beweist nichts.

Füge keine Schlüsselwörter aus einer fehlschlagenden Abfrage hinzu – so enden Beschreibungen wie eine Schlüsselwortliste und passen nicht mehr zu echten Prompts.

Verwandte Skills