TPTruPDF

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 bundle

The 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'); // false

Plugins

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: () => { /* … */ },
    },
  ],
};