Web SDKv1.0.0

Locale

The viewer's language, and your translations. The SDK ships English only: the string table is the contract, and you supply the languages. A translation is a Partial<UIStrings> (UIStringKey = keyof typeof EN_STRINGS): the keys are typed, so a misspelt key is a compile error and your editor completes them. The full list, with the English text, is in the exported EN_STRINGS; the groups are summarized in the table below.
LocaleConfigconfig.locale

Example

viewer.tsTypeScript
import type { UIStrings } from '@kernstra/pdf-web-sdk';

const german: Partial<UIStrings> = {
  'cluster.highlight': 'Markieren', // the toolbar button
  'tool.sign': 'Unterschreiben',
  'common.download': 'Herunterladen', // the toolbar button; 'download.title' is the dialog's title
  'common.pageCount': '{n, plural, one {# Seite} other {# Seiten}}',
};

new PDFViewer(container, doc, {
  locale: {
    lang: user.language, // 'de-AT'
    translations: {
      de: german,
      fr: { 'cluster.highlight': 'Surligner', 'tool.sign': 'Signer' },
    },
  },
});

Options 3

langstringDefault'en'

A BCP-47 tag, e.g. 'de-AT'. It picks a table from translations and drives numbers and dates through Intl: zoom percentages, file sizes (the number; the unit is the common.bytes.* key, so French can say Mo), page counts, and dates in the signatures panel. Dates use the language's medium style ("Oct 7, 2026", "07.10.2026"); a signing time in the signatures panel shows the time the file records, not converted to the reader's time zone. Lists such as the Image tool's accepted types are joined the language's way ("PNG, JPEG, or GIF"). The viewer sets lang on its own element from this value, so screen readers pronounce the labels in that language; dialogs that open outside the viewer carry it too.

An invalid lang formats numbers and dates in English (a translation stored under exactly that string is still used). lang and the keys of translations are read in their canonical form (de-at becomes de-AT).

stringsPartial<UIStrings>
Overrides for this viewer, whatever the language. strings wins over translations. Some tools have a short label for the toolbar and a full one for tooltips: tool.editText.short, tool.addText.short and tool.managePages.short. Translate both.
stringsTypeScript
new PDFViewer(container, doc, {
  locale: { strings: { 'common.download': 'Save a copy', 'tool.sign': 'Sign here' } },
});
translationsRecord<string, Partial<UIStrings>>
Several languages; lang picks one. Type a complete table as UIStrings (satisfies UIStrings) and the compiler lists every key you have not translated. Load it however you like (a dynamic import() per language works), but have it in hand before you build the viewer: translations are read once, when the viewer is built. A key the SDK does not have is ignored without a warning, so after upgrading, compare your table with EN_STRINGS.
translationsTypeScript
import { EN_STRINGS } from '@kernstra/pdf-web-sdk';
const missing = Object.keys(EN_STRINGS).filter((key) => !(key in german));

The key groups of EN_STRINGS (725 keys)

GroupKeysWhat it covers
common.*26Shared button labels (Cancel, Close, Done, Save, Delete, Download, Print …), size units (common.bytes.*), page labels and the page-count plural.
tool.*, group.*, cluster.*, key.*45Tool names (with the .short toolbar labels), toolbar group and cluster labels, key names.
viewer.*, download.*, print.*, pageScope.*35The viewer's own labels and loading/error messages, the Download and Print dialogs, the page-scope choices (all, current, range).
fields.*, thumbs.*, search.*, nav.*, toolbar.*, permission.*, certified.*, sidebar.*, outline.*, attachments.*, signatures.*, textLayer.*, phone.*, links.*135Form fields and the stepper, thumbnails, the search bar, the navigation bar, the toolbar, document permissions and certification notices, the sidebar and its Outline, Attachments and Signatures tabs, the text layer, the phone shell, and link pills.
states.*, dropZone.*, progress.*, colorPicker.*, color.*, weight.*54The document states (error, password, offline), the drop zone, progress cards, the color picker, the built-in color names and line weights.
confirm.*22The confirmation questions, their messages and the Discard / Replace buttons (see Confirmations).
pages.*21The Manage Pages dialog.
security.*69The Security tool: passwords and permissions.
object.*, subject.*, erase.*, highlight.*, image.*, link.*, note.*, ink.*, select.*, sign.*, stamp.*, marks.*177Selected objects and their action bar, annotation subjects, and the Erase, Highlight, Image, Link, Note, Select, Sign, Stamp and Marks tools, including the built-in ink names and the standard stamp wordings.
comments.*36The Comments panel: replies and review statuses.
signature.*33The signature dialog and its fonts; signature.alt is what a screen reader reads for a placed signature.
text.*, addText.*, freeText.*, editText.*33The Add Text, Text box and Edit Text tools and their options bars.
drawing.*, shape.*, style.*, ending.*39The drawing tools and shapes, the border Style picker and the Line and Arrow Ends picker.

Notes

How a key resolves. strings, then translations[lang], then the base language (de-AT → de), then English. A partial translation shows English where it has gaps, not a key. An empty string is a value: '' shows nothing. The fallback goes straight from the full tag to its first part: zh-Hant-TW falls back to zh, never to zh-Hant.

Placeholders and plurals. Some values carry {name} placeholders — keep them; a number put into one is formatted for lang (1234 → "1,234" in English, "1.234" in German), and a placeholder you misspell prints as written. Counts use a plural, {n, plural, one {# page} other {# pages}}: # is the number, and the branches are the language's own plural categories (zero, one, two, few, many, other) or an exact value such as =0 or =2, chosen with Intl.PluralRules for lang (an exact value wins; other is the fallback). For example pl: { 'common.pageCount': '{n, plural, one {# strona} few {# strony} many {# stron} other {# strony}}' }.

The syntax has {name} and plural only. select, selectordinal, offset: and apostrophe quoting are not supported, and there is no escape character: a select prints as written, and so does a { that is never closed. Inside a plural branch every # is the number. A branch missing for a count falls back to other, or to the first branch when there is no other.

What goes into the PDF. The standard stamps' words (a tick, a cross and a dot have none) and the date a dated stamp burns in are written with the viewer's language at the moment the stamp is placed — they are content, and stay as written if the document is later opened in another language. A form field that uses Acrobat's number, date or time formats shows and stores its value in the field's own format, as Acrobat does, whatever lang is.

What stays English. Error messages (SDKError.message, the error event's) are for your logs; show your own copy for the error code (see Errors). What the SDK shows or tells a screen reader about an error is from the table (viewer.error.*, states.error.*). The watermark is not translatable; the "License required" popup is outside the viewer and its table, and takes your own words through Kernstra.init({ licensePopup }) — see Licensing.

Right-to-left languages. You can translate the table into Arabic, Hebrew or Persian, but the viewer's layout stays left-to-right: toolbars, panels and dialogs are not mirrored. Document text in those scripts renders and searches normally. Edit Text and Add Text handle text that is entirely right-to-left; a line that mixes right-to-left and left-to-right text is not yet laid out in mixed directions.

Changing language means building a new viewer: the chrome is built once. The same is true of theme, toolbar (including icons and actions), the picker lists and layout: a viewer reads its configuration once. To switch, call viewer.destroy() and build a new viewer on the same doc. The document and the edits made to it are kept, but not what was typed or signed into form fields, which lives in the viewer until export: read doc.forms.getValues() first and give it back to doc.forms.setValues() once the new viewer is open. Undo history and the current page start fresh (call goToPage to restore the page).

Outside a viewer, createDropZone, createPasswordPrompt and createLoadError take the same object as options.locale, as does PDFViewer.showLoadingIndicator(container, { loader, locale }).