Localização
Toda string embutida no kit (468 rótulos em 77 conjuntos: aria-labels, anúncios de leitor de tela, o texto de botões que você não escreveu, placeholders) é traduzida por um único provider. Monte-o uma vez com um pacote de idioma e todo componente do goodui fala aquele idioma; formatos de número, data e moeda acompanham via Intl, e árabe e hebraico recebem a direção certa. Apps que nunca o definem continuam em inglês com formatos en-US, sem carregar nada a mais.
Instalar
npx shadcn@latest add https://goodui.dev/r/locale.json https://goodui.dev/r/locale-tr.jsonlocale vai para lib/goodui-locale.ts (todo componente com rótulos já depende dele, então você provavelmente já o tem). Um pacote vai para lib/goodui-locales/<lang>.ts e não depende de mais nada; instale só os idiomas que você entrega.
Defina o idioma
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 é uma tag BCP 47 e controla todos os formatos Intl do kit ("de-AT", "pt-BR", "en-GB" funcionam). labels é o pacote. Para um seletor de idioma, mantenha a tag no estado e escolha o pacote em um mapa de imports lazy; providers aninhados funcionam, então uma tela pode rodar em outro idioma.
Pacotes
18 idiomas, um arquivo cada, todos os rótulos de todos os componentes. Nomes nativos, como um seletor os mostraria:
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 também existe: é gerado a partir dos componentes e é a referência contra a qual todos os outros pacotes são verificados. Importe-o quando quiser mudar os rótulos em inglês em todo o app.
RTL
Os componentes leem a direção de escrita do DOM (propriedades lógicas, :dir(rtl), ícones espelhados), então defina-a você mesmo no documento: <html lang="ar" dir="rtl">. O provider nunca toca em <html>; ele só deriva dir de lang (ar, he, fa, ur são RTL) para os componentes que pedem, e você pode passar dir para sobrescrever. dirOf("ar") é exportado para o seu próprio código de layout.
Formatos Intl
Componentes que formatam valores (number-flow, counter-up, stat-card, meter, sparkline-draw, data-grid, date-picker, number-input) aceitam uma prop locale. Sem ela, agora vale o idioma do provider em vez de "en-US"; uma prop explícita continua vencendo. Os mesmos formatadores ficam à sua disposição pelo 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 €"As instâncias ficam em cache por idioma e opções, então chamá-las no render é tranquilo. Fora do React, createFormatters(lang) retorna as mesmas quatro funções.
Sobrescreva um rótulo
A prop labels de qualquer componente continua vencendo o pacote, então uma única instância pode dizer outra coisa. Para uma mudança em todo o app, espalhe o pacote com spread:
<Dialog labels={{ confirm: "Rezervasyonu iptal et" }} … /> {/* this dialog only */}
const labels = { ...tr, alert: { ...tr.alert, dismiss: "Kapat" } } // every alert
<GooduiLocaleProvider lang="tr" labels={labels}>Rótulos com valores são funções, então os plurais são de verdade: results: (n) => plural("pl", n, { one: "1 wynik", few: `${n} wyniki`, many: `${n} wyników`, other: `${n} wyniku` }). plural() vem em lib/goodui-locale e encapsula Intl.PluralRules.
Adicione um idioma
Copie lib/goodui-locales/en.ts para um novo arquivo e traduza os valores; mantenha as chaves e as assinaturas das funções. O manifesto, lib/locales/labels-manifest.json no repositório, lista cada chave com seu tipo, parâmetros e onde é usada (aria-label, leitor de tela, texto visível). Nosso próprio build roda node scripts/extract-labels.ts, que regenera lib/goodui-locales/en.ts a partir dos componentes e falha quando qualquer pacote está sem um componente, uma chave ou um parâmetro, então os 18 pacotes nunca ficam para trás dos componentes. Pull requests com novos idiomas são bem-vindos.
Experimente
O Playground de todo componente Core tem um seletor de idioma: a prévia é renderizada de novo naquele idioma (RTL para árabe e hebraico) e o snippet impresso inclui o provider. Qualquer página de prévia aceita ?lang=tr (e &dir=rtl para forçar uma direção), por exemplo /preview/c/pagination?lang=ar.
goodui Native
Os mesmos pacotes e manifesto estão planejados para o kit React Native (um LocaleProvider em foundation, os mesmos ids de componente); até lá, os componentes Native recebem suas strings via props e objetos labels por tela.