Summary: Standardize on i18next and react-i18next for internationalization and localization in kodesk app.
Created: 21 July, 2023
Status: Draft
Owner: Gema Anggada ([email protected])
Approvers:
This RFC proposes adopting the i18next internationalization framework and its React integration library react-i18next to handle localization in our React application.
At the moment kodesk doesn't have multiple languages implementation. As we plan to expand the apps to Bahasa Indonesia we will need to implement a scalable i18n solution.
i18next provides translation support with extensions for localization formatting, plurals, context, and more. React-i18next seamlessly integrates i18next with React for component-based translations. These libraries are widely used and well-supported by the community.
Adopt i18next and react-i18next as our standard i18n libraries as opposed to implementing in-house utilities. This will enable us to:
- Centralize and standardize translation files across the app
- Scale to multiple languages more easily
- Access translations in components via hooks
- Support plurals, context, formatting, namespaces
- Enable collaboration by translators with minimal code changes
t
t
wrapper function accepts the first string as the key and nested key accessor. Provided by useTranslation
hook. docs
example:
// t wrapper
t('greeting', {name: 'Jane'})
t('dashboard.warning', {name: 'Jane'})
// translation key
{
greeting: 'hello {{name}}'
dashboard: {
warning: '{{name}} You are not allowed for that action!'
}
}
Trans Component & Plurals
For existing React Code that uses nested element we can easily wrap in Trans Component. docs
import { Trans } from 'react-i18next';
function MyComponent({ person, messages }) {
const { name } = person;
const count = messages.length;
return (
<Trans i18nKey="userMessagesUnread" count={count}>
Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
);
}
// and translation strings like these including plurals feature:
"nameTitle": "This is your name",
"userMessagesUnread_one": "Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>.",
"userMessagesUnread_other": "Hello <1>{{name}}</1>, you have {{count}} unread messages. <5>Go to messages</5>.",
example file for English:
export const en = {
noPTO: 'You have not requested a time off.',
slogan: 'Your Work Assistant On The Go',
subSlogan:
'Access your work agenda, connect with your co-workers, and manage your time-off all in one place.',
googleSignIn: 'Continue with Google',
noData: 'No data available right now',
viewToday: 'View Today',
search: 'Search {{item}}',
requestTimeOff: 'Request Time Off',
dateOfHire: 'DATE OF HIRE',
title: 'TITLE',
};
example translation file for Bahasa:
export const id = {
noPTO: 'Anda belum pernah meminta cuti',
slogan: 'Asisten Kerja Anda',
subSlogan:
'Akses agenda kerja Anda, berhubung dengan rekan kerja, dan kelola waktu libur Anda semuanya dalam satu tempat',
googleSignIn: 'Lanjut menggunakan Google',
noData: 'Tidak ada data ditemukan',
viewToday: 'Hari ini',
search: 'Cari {{item}}',
requestTimeOff: 'Minta Cuti',
dateOfHire: 'TANGGAL MULAI',
title: 'JABATAN',
};
- Add i18next and react-i18next packages
- Configure i18next initialization and options
- define translation files in typescript files
- Update components to use
useTranslation
hook for accessing translations
Current ongoing implementation: #583
- Integration - Integrating translation
t
wrapper to the existing codebase.
- Developers use
useTranslation
hook in components - Change language via language selector (still for discussion)
- Fallback to English if translation is unavailable
- Finalize implementation details
- Providing Bahasa Indonesia translations of existing copy
Let me know if any sections need additional detail! I'm happy to revise and expand this draft RFC.