Skip to main content

Version: 23.04

Locales

Internationalization (i18n) appears to be simple but can be complex. Some considerations are:

  • Front-end internationalization
  • Internationalization of server
  • Internationalized resource file management
  • How to collaborate between projects, developers and translators
  • Internationalization of dates and times

Internationalization implementations are often tied to specific technology stacks. This internationalization setup is only for the React technology stack and does not involve server-side internationalization.

Front-end internationalization

The core steps of internationalization are as follows:

  1. Add the desired locale to the transact-config configuration. If omitted, the default locale is en.
  2. Create and import a messages file, stored as a key-value object in the src/locales folder.
  3. Import and re-export those locale message files in src/locales/index.ts.
  4. Pass the configs and messages to the App init.
src/locales/index.ts
import en from './en';
import es from './es';
import pt from './pt';

export default {
en,
es,
pt,
};

The Workspaces app generates a list of locales in the dropdown, matching the exported locales listed above with the list below to determine which locales appear.

{ value: 'fr', key: 'fr_FR', label: 'French' },
{ value: 'it', key: 'it_IT', label: 'Italian' },
{ value: 'en', key: 'en_US', label: 'English' },
{ value: 'pt', key: 'pt_PT', label: 'Portuguese' },
{ value: 'ru', key: 'ru_RU', label: 'Russian' },
{ value: 'es', key: 'es_ES', label: 'Spanish' },
{ value: 'sv', key: 'sv_SE', label: 'Swedish' },
{ value: 'de', key: 'de_DE', label: 'German' },
{ value: 'nl', key: 'nl_NL', label: 'Dutch' },
{ value: 'ca', key: 'ca_ES', label: 'Catalan' },
{ value: 'cs', key: 'cs_CZ', label: 'Czech' },
{ value: 'ko', key: 'ko_KR', label: 'Korean' },
{ value: 'et', key: 'et_EE', label: 'Estonian' },
{ value: 'sk', key: 'sk_SK', label: 'Slovak' },
{ value: 'ja', key: 'ja_JP', label: 'Japanese' },
{ value: 'tr', key: 'tr_TR', label: 'Turkish' },
{ value: 'zh', key: 'zh_TW', label: 'Chinese' },
{ value: 'fi', key: 'fi_FI', label: 'Finnish' },
{ value: 'pl', key: 'pl_PL', label: 'Polish' },
{ value: 'bg', key: 'bg_BG', label: 'Bulgarian' },
{ value: 'vi', key: 'vi_VN', label: 'Vietnamese' },
{ value: 'th', key: 'th_TH', label: 'Thai' },
{ value: 'fa', key: 'fa_IR', label: 'Persian' },
{ value: 'el', key: 'el_GR', label: 'Greek' },
{ value: 'nb', key: 'nb_NO', label: 'Norwegian Bokmål' },
{ value: 'sr', key: 'sr_RS', label: 'Serbian' },
{ value: 'sl', key: 'sl_SI', label: 'Slovenian' },
{ value: 'is', key: 'is_IS', label: 'Icelandic' },
{ value: 'ar', key: 'ar_EG', label: 'Arabic' },
{ value: 'uk', key: 'uk_UA', label: 'Ukrainian' },
{ value: 'ku', key: 'ku_IQ', label: 'Kurdish' },

We use the date-fns library for date translations which requires some unique locale data when doing internationalization, mainly for relative time translation such as yesterday, today, tomorrow, N minutes ago, or N months ago. Consequently, it's important to import the correct locale at the begining of the file. To learn more, see, the date-fns documentation.

Internationalized resource file management

The above document discusses the steps of how to internationalize after the introduction of messages files. Next, let's talk about the management of international resource files.

Currently we manage the resource file in the src/locales folder:

.
├── en.ts
├── es.ts
└── pt.ts

\*.ts is a resource file that returns an object; the key for our translation id, and the value for the specific language translation. For example:

src/locales/en.ts
export default {
Home: 'Home',
All: 'All',
Apply: 'Apply',
Process: 'Process',
Helpdesk: 'Helpdesk',
...
}
src/locales/es.ts
export default {
Home: 'Hogar',
All: 'Todos',
Applications: 'Aplicaciones',
Review: 'Revisar',
Funding: 'Fondos',
...
}