@workos-inc/widgets-i18n
v0.1.0
Published
A package providing internationalization support for [WorkOS Widgets](https://workos.com/docs/widgets).
Maintainers
Keywords
Readme
WorkOS Widgets Internationalization
A package providing internationalization support for WorkOS Widgets.
Features
- 90+ supported locales: Comprehensive language support including regional variants (e.g.,
en-US,en-GB,fr-CA,zh-CN) - RTL support: Automatic right-to-left text direction for Arabic (
ar), Farsi (fa), Hebrew (he), and Urdu (ur) - Dynamic dictionary loading: Locale dictionaries are lazily loaded to minimize initial bundle size
API
Components
WorkOsLocaleProvider: React context provider that wraps your application to enable localization for WorkOS widgets
Functions
getDictionary(locale): Asynchronously loads the translation dictionary for a given localeisValidLocale(locale): Type guard to check if a string is a valid locale codegetDir(locale): Returns"ltr"or"rtl"based on the locale's text directiongetLocaleCodes(): Returns aSetof all supported locale codes
Constants & Types
LocaleCode: TypeScript type representing supported locale codesWorkOsLocaleProviderProps: Props interface for the locale provider
Usage
Wrap your application with WorkOsLocaleProvider to enable localization:
import { WorkOsLocaleProvider } from "@workos-inc/widgets-i18n";
function App() {
return (
<WorkOsLocaleProvider locale="en-US">
{/* your app goes here */}
</WorkOsLocaleProvider>
);
}Server-Side Locale Detection
Detect the user's preferred locale from request headers:
// utils/locale.ts
import {
getDir,
getLocaleCodes,
isValidLocale,
type LocaleCode,
} from "@workos-inc/widgets-i18n";
import Negotiator from "negotiator";
import * as React from "react";
const DEFAULT_LOCALE = "en-US" satisfies LocaleCode;
/**
* For apps that support React Server Components, we recommend caching
* the results of this function using React.cache.
*
* @param acceptLanguage - The value of the accept language header from the request.
* Different frameworks will offer different ways to access this.
*/
export const getLocale = React.cache(
async (acceptLanguage = DEFAULT_LOCALE): Promise<LocaleCode> => {
const negotiator = new Negotiator({
headers: { "accept-language": acceptLanguage },
});
const locale = negotiator.language(Array.from(getLocaleCodes()));
return isValidLocale(locale) ? locale : DEFAULT_LOCALE;
},
);
export function getLocaleDir(locale: LocaleCode) {
return getDir(locale);
}Apply localization at the root layout level:
import { WorkOsLocaleProvider } from "@workos-inc/widgets-i18n";
import { getLocale, getLocaleDir } from "~/utils/locale";
import { getRequest } from "your-favorite-framework";
import "@workos-inc/widgets/styles.css";
export default async function RootLayout({ children }) {
const request = getRequest();
const locale = await getLocale(request.headers.get("accept-language"));
const direction = getLocaleDir(locale);
return (
<WorkOsLocaleProvider locale={locale}>
<html dir={direction} lang={locale}>
<body>{children}</body>
</html>
</WorkOsLocaleProvider>
);
}Server-Side Dictionary Loading (React 19)
For React 19 applications, you can pre-load the dictionary on the server using React.use():
import { getDictionary, WorkOsLocaleProvider } from "@workos-inc/widgets-i18n";
import * as React from "react";
function LocalizedApp({ locale, children }) {
const messages = React.use(getDictionary(locale));
return (
<React.Suspense fallback={<Loading />}>
<WorkOsLocaleProvider locale={locale} initialMessages={messages}>
{children}
</WorkOsLocaleProvider>
</React.Suspense>
);
}Supported locales
| Locale code | Language | Autonym |
| ----------- | ----------------------- | ----------------------- |
| af | Afrikaans | Afrikaans |
| am | Amharic | አማርኛ |
| ar | Arabic | العربية |
| bg | Bulgarian | Български |
| bn | Bengali (Bangla) | বাংলা |
| bs | Bosnian | Bosanski |
| ca | Catalan | Català |
| cs | Czech | Čeština |
| da | Danish | Dansk |
| de | German | Deutsch |
| de-DE | German (Germany) | Deutsch (Deutschland) |
| el | Greek | Ελληνικά |
| en | English | English |
| en-AU | English (Australia) | English (Australia) |
| en-CA | English (Canada) | English (Canada) |
| en-GB | English (UK) | English (UK) |
| en-US | English (US) | English (US) |
| es | Spanish | Español |
| es-419 | Spanish (Latin America) | Español (Latinoamérica) |
| es-ES | Spanish (Spain) | Español (España) |
| es-US | Spanish (US) | Español (EE.UU.) |
| et | Estonian | Eesti |
| fa | Farsi (Persian) | فارسی |
| fi | Finnish | Suomi |
| fil | Filipino (Tagalog) | Filipino |
| fr | French | Français |
| fr-BE | French (Belgium) | Français (Belgique) |
| fr-CA | French (Canada) | Français (Canada) |
| fr-FR | French (France) | Français (France) |
| fy | Frisian | Frysk |
| gl | Galician | Galego |
| gu | Gujarati | ગુજરાતી |
| ha | Hausa | هَرْشٜن هَوْس |
| he | Hebrew | עברית |
| hi | Hindi | हिन्दी |
| hr | Croatian | Hrvatski |
| hu | Hungarian | Magyar |
| hy | Armenian | Հայերեն |
| id | Indonesian | Bahasa Indonesia |
| is | Icelandic | Íslenska |
| it | Italian | Italiano |
| it-IT | Italian (Italy) | Italiano (Italia) |
| ja | Japanese | 日本語 |
| jv | Javanese | ꦧꦱꦗꦮ |
| ka | Georgian | ქართული |
| kk | Kazakh | Қазақ тілі |
| km | Khmer | ខេមរភាសា |
| kn | Kannada | ಕನ್ನಡ |
| ko | Korean | 한국어 |
| lt | Lithuanian | Lietuvių |
| lv | Latvian | Latviešu |
| mk | Macedonian | Македонски |
| ml | Malayalam | മലയാളം |
| mn | Mongolian | Монгол |
| mr | Marathi | मराठी |
| ms | Malay | Bahasa Melayu |
| my | Burmese | မြန်မာ |
| nb | Norwegian Bokmål | Norsk Bokmål |
| ne | Nepali | नेपाली भाषा |
| nl | Dutch | Nederlands |
| nl-BE | Flemish | Vlaams |
| nl-NL | Dutch (Netherlands) | Nederlands (Nederland) |
| nn | Norwegian Nynorsk | Norsk Nynorsk |
| no | Norwegian | Norsk |
| pa | Punjabi | ਪੰਜਾਬੀ |
| pl | Polish | Polski |
| pt | Portuguese | Português |
| pt-BR | Portuguese (Brazil) | Português (Brasil) |
| pt-PT | Portuguese (Portugal) | Português (Portugal) |
| ro | Romanian | Română |
| ru | Russian | Русский |
| sk | Slovak | Slovenčina |
| sl | Slovenian | Slovenščina |
| sq | Albanian | Shqip |
| sr | Serbian | Српски |
| sv | Swedish | Svenska |
| sw | Swahili | Kiswahili |
| ta | Tamil | தமிழ் |
| te | Telugu | తెలుగు |
| th | Thai | ไทย |
| tr | Turkish | Türkçe |
| uk | Ukrainian | Українська |
| ur | Urdu | اُردُو |
| uz | Uzbek | Ózbekça |
| vi | Vietnamese | Tiếng Việt |
| zh | Chinese | 中文 |
| zh-CN | Chinese (Simplified) | 中文 (中国) |
| zh-HK | Chinese (Hong Kong) | 中文(香港) |
| zh-TW | Chinese (Taiwan) | 中文(台灣) |
| zu | Zulu | isiZulu |
