Lokalisierung
Jeder eingebaute String im Kit (468 Labels in 77 Label-Sets: aria-labels, Screenreader-Ansagen, der Text von Buttons, die du nicht geschrieben hast, Platzhalter) wird von einem Provider übersetzt. Einmal mit einem Sprachpaket mounten, und jede goodui-Komponente spricht diese Sprache; Zahlen-, Datums- und Währungsformate folgen über Intl, Arabisch und Hebräisch bekommen ihre Schreibrichtung. Apps, die ihn nie setzen, bleiben bei Englisch und en-US-Formaten, ohne dass etwas Zusätzliches geladen wird.
Installieren
npx shadcn@latest add https://goodui.dev/r/locale.json https://goodui.dev/r/locale-tr.jsonlocale landet in lib/goodui-locale.ts (jede Komponente mit Labels hängt bereits davon ab, du hast es also meist schon). Ein Paket landet in lib/goodui-locales/<lang>.ts und hängt von nichts anderem ab; installiere nur die Sprachen, die du auslieferst.
Sprache setzen
import { GooduiLocaleProvider } from "@/lib/goodui-locale"
import tr from "@/lib/goodui-locales/tr"
export default function RootLayout({ children }) {
return (
<html lang="tr">
<body>
<GooduiLocaleProvider lang="tr" labels={tr}>{children}</GooduiLocaleProvider>
</body>
</html>
)
}lang ist ein BCP 47-Tag und steuert jedes Intl-Format im Kit ("de-AT", "pt-BR", "en-GB" sind in Ordnung). labels ist das Paket. Für einen Sprachumschalter hältst du das Tag im State und wählst das Paket aus einer Map mit Lazy-Imports; verschachtelte Provider funktionieren, ein Screen kann also in einer anderen Sprache laufen.
Pakete
18 Sprachen, eine Datei pro Sprache, jedes Label jeder Komponente. Eigennamen, wie ein Umschalter sie anzeigen würde:
locale-tr: Türkçelocale-de: Deutschlocale-fr: Françaislocale-es: Españollocale-it: Italianolocale-pt-BR: Português (Brasil)locale-nl: Nederlandslocale-pl: Polskilocale-ru: Русскийlocale-hi: हिन्दीlocale-id: Bahasa Indonesialocale-vi: Tiếng Việtlocale-th: ไทยlocale-ja: 日本語locale-ko: 한국어locale-zh-CN: 中文(简体)locale-ar: العربية (RTL)locale-he: עברית (RTL)
locale-en gibt es ebenfalls: Es wird aus den Komponenten generiert und ist die Referenz, gegen die jedes andere Paket geprüft wird. Importiere es, wenn du englische Labels app-weit ändern willst.
RTL
Komponenten lesen die Schreibrichtung aus dem DOM (logische Properties, :dir(rtl), gespiegelte Icons), setz sie also selbst am Dokument: <html lang="ar" dir="rtl">. Der Provider fasst <html> nie an; er leitet nur dir aus lang ab (ar, he, fa, ur sind RTL) für Komponenten, die danach fragen, und du kannst dir übergeben, um das zu überschreiben. dirOf("ar") ist für deinen eigenen Layout-Code exportiert.
Intl-Formate
Komponenten, die Werte formatieren (number-flow, counter-up, stat-card, meter, sparkline-draw, data-grid, date-picker, number-input), nehmen ein locale-Prop. Ohne Angabe ist es jetzt die Provider-Sprache statt "en-US"; ein explizites Prop gewinnt weiterhin. Dieselben Formatter bekommst du über den Hook:
import { useGooduiLocale } from "@/lib/goodui-locale"
const { lang, dir, formatNumber, formatDate, formatRelative, formatCurrency } = useGooduiLocale()
formatNumber(12345.6) // "12.345,6" in de
formatDate(booking.start) // "3 Kas 2026" in tr; pass Intl.DateTimeFormat options for other styles
formatRelative(-2, "hour") // "vor 2 Stunden"
formatCurrency(49, "EUR") // "49,00 €"Instanzen werden pro Sprache und Optionen gecacht, der Aufruf im Render ist also unproblematisch. Außerhalb von React liefert createFormatters(lang) dieselben vier Funktionen.
Ein Label überschreiben
Das labels-Prop jeder Komponente gewinnt weiterhin über das Paket, eine einzelne Instanz kann also etwas anderes sagen. Für eine app-weite Änderung spreadest du das Paket:
<Dialog labels={{ confirm: "Rezervasyonu iptal et" }} … /> {/* this dialog only */}
const labels = { ...tr, alert: { ...tr.alert, dismiss: "Kapat" } } // every alert
<GooduiLocaleProvider lang="tr" labels={labels}>Labels mit Werten sind Funktionen, Plurale sind also echt: results: (n) => plural("pl", n, { one: "1 wynik", few: `${n} wyniki`, many: `${n} wyników`, other: `${n} wyniku` }). plural() liegt in lib/goodui-locale und kapselt Intl.PluralRules.
Eine Sprache hinzufügen
Kopiere lib/goodui-locales/en.ts in eine neue Datei und übersetze die Werte; Keys und Funktionssignaturen bleiben. Das Manifest, lib/locales/labels-manifest.json im Repo, listet jeden Key mit Art, Parametern und Einsatzort (aria-label, Screenreader, sichtbarer Text). Unser eigener Build führt node scripts/extract-labels.ts aus, das lib/goodui-locales/en.ts aus den Komponenten neu erzeugt und fehlschlägt, sobald einem Paket eine Komponente, ein Key oder ein Parameter fehlt; die 18 Pakete können den Komponenten also nie hinterherhinken. Pull Requests mit neuen Sprachen sind willkommen.
Ausprobieren
Der Playground jeder Core-Komponente hat eine Sprachauswahl: Die Vorschau rendert in dieser Sprache neu (RTL für Arabisch und Hebräisch), und das ausgegebene Snippet enthält den Provider. Jede Vorschauseite nimmt ?lang=tr (und &dir=rtl, um eine Richtung zu erzwingen), z. B. /preview/c/pagination?lang=ar.
goodui Native
Dieselben Pakete und dasselbe Manifest sind für das React-Native-Kit geplant (ein LocaleProvider in foundation, dieselben Komponenten-IDs); bis dahin bekommen Native-Komponenten ihre Strings über Props und labels-Objekte pro Screen.