Internationalization
31 locales out of the box, RTL for Arabic / Hebrew / Farsi, lazy bundle loading. English ships in the main bundle; every other locale is loaded on demand as its own chunk, so users only pay for the language they select.
Supported locales
import { SUPPORTED_LOCALES, LOCALE_LABELS } from '@trupdf/viewer';
SUPPORTED_LOCALES;
// ['en','es','fr','de','it','pt','pt-BR','nl','sv','no','da','fi',
// 'pl','cs','hu','tr','ru','uk','el','ar','he','fa','hi','bn','th',
// 'vi','id','zh-CN','zh-TW','ja','ko']LOCALE_LABELS maps each code to its native display name
(fr → 'Français', ja → '日本語', …).
RTL: ar, he, fa. The viewer flips layout automatically and sets
dir="rtl" / lang on the document element.
Initial locale
Set the language prop on the viewer:
<DocViewer source="…" language="fr" licenseManager={license} />Switch locale at runtime
import { changeLanguage } from '@trupdf/viewer';
await changeLanguage('fr'); // lazy-loads the bundleThe locale switch is global — all mounted viewers re-render with the new bundle. Rapid consecutive calls are coalesced: if a newer call supersedes one still loading its bundle, the older one becomes a no-op so a slow chunk can never clobber the newer locale.
Locale picker UI
A built-in <LanguageSwitcher /> (native <select>, listing every
locale by its native name) ships as a controlled component:
import { LanguageSwitcher, changeLanguage } from '@trupdf/viewer';
const [locale, setLocale] = useState('en');
<LanguageSwitcher
current={locale}
onChange={(next) => {
setLocale(next);
void changeLanguage(next);
}}
/>;Hosts that want a custom picker call changeLanguage directly.
Provider
Optionally wrap your app to drive the locale declaratively:
import { I18nProvider } from '@trupdf/viewer';
export function App({ children }: { children: React.ReactNode }) {
return <I18nProvider language="en">{children}</I18nProvider>;
}The provider is not required — TruPDF components always resolve
against the shared TruPDF i18n instance, so <DocViewer language> and
changeLanguage() work without any wrapper.
Custom translations
Override / extend any key on the shared instance (namespace
'trupdf'):
import { getTruPDFI18n } from '@trupdf/viewer';
const i18n = getTruPDFI18n();
i18n.addResourceBundle(
'en',
'trupdf',
{
toolbar: { search: 'Find in document' },
},
true,
true,
);Missing keys fall back to English automatically.
Inside components
import { useTranslation } from '@trupdf/viewer';
function MyButton() {
const { t } = useTranslation();
return <button>{t('toolbar.print')}</button>;
}The hook is pre-bound to the TruPDF instance and the trupdf
namespace — no arguments needed, and it works with or without an
I18nProvider in the tree.
Check RTL
import { isRTL } from '@trupdf/viewer';
isRTL('ar'); // true
isRTL('en'); // falsePlugins
Register your plugin's strings before installing it, then resolve them through the shared instance so they respect the active locale and any host overrides:
import { getTruPDFI18n } from '@trupdf/viewer';
const i18n = getTruPDFI18n();
i18n.addResourceBundle('en', 'trupdf', {
acme: { markReviewed: 'Mark reviewed' },
}, true, false);
i18n.addResourceBundle('fr', 'trupdf', {
acme: { markReviewed: 'Marquer comme relu' },
}, true, false);
const plugin = {
id: 'acme-review',
toolbar: [
{
id: 'acme-mark-reviewed',
label: i18n.t('acme.markReviewed'),
handler: () => { /* … */ },
},
],
};