Learn how to display Widgets in multiple languages.
Configure widget localization to display UI elements in your users’ preferred language, with support for 90 languages out of the box.

Dates are also formatted with respect to the user’s locale.
Add localization support through the separate @workos-inc/widgets-i18n package. This opt-in approach keeps the core Widgets package lightweight for applications that do not require multilingual behavior.
Translation dictionaries are loaded lazily, so only the language bundle matching the end user’s locale is downloaded at runtime.
Install the package:
npm install @workos-inc/widgets-i18n
Wrap your application with the WorkOsLocaleProvider and pass the user’s locale:
import { WorkOsLocaleProvider } from '@workos-inc/widgets-i18n'; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const locale = await getLocale(); // read from request headers const direction = getLocaleDir(locale); return ( <WorkOsLocaleProvider locale={locale}> <html dir={direction} lang={locale}> <body>{children}</body> </html> </WorkOsLocaleProvider> ); }
Place the WorkOsLocaleProvider around your entire application, similar to other context providers.
Use the utilities exported from @workos-inc/widgets-i18n to detect and validate locales:
getLocaleCodes() – Set of all supported locale codesisValidLocale() – Validates whether a string is a supported locale codegetDir() – Returns the text direction ('ltr' or 'rtl') for a localeDetect the user’s locale from the accept-language header in Next.js:
import { getLocaleCodes, getDir, isValidLocale, } from '@workos-inc/widgets-i18n'; import Negotiator from 'negotiator'; import { headers } from 'next/headers'; const DEFAULT_LOCALE = 'en-US'; export async function getLocale(): Promise<string> { const headersList = await headers(); const acceptLanguage = headersList.get('accept-language') ?? ''; 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: string): 'ltr' | 'rtl' { return getDir(locale); }
For right-to-left languages like Arabic and Hebrew, set the dir attribute on your HTML element. Call the getDir() function to determine the appropriate text direction:
import { getDir } from '@workos-inc/widgets-i18n'; const direction = getDir(locale); // Returns 'ltr' or 'rtl' return ( <html dir={direction} lang={locale}> {/* ... */} </html> );
Widgets will automatically inherit their text direction based on the nearest ancestor’s dir attribute.
Widgets support the same locales as the AuthKit hosted UI. See the AuthKit localization documentation for the full list of supported locale codes.