Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add i18n ADR #1794

Merged
merged 2 commits into from
Dec 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions docs/adr/adr_i18n.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# ADR: Adapt boxtribute for internationalization

[Trello-card](https://trello.com/c/jkdpDyyX/761-check-localization-and-language-options-implementation-in-new-old-app-database?search_id=7c64905c-bda4-4164-9703-9e6a6a933e28)

Decision Deadline: Dec 1st 2024

Author: [Philipp](https://github.com/orgs/boxwise/people/pylipp)

## Status

Proposed.

## Context / Problem Statement

Internationalization (i18n) is the process of designing and developing software so it can be adapted for users of different cultures and languages.

Currently, the boxtribute web app is not capable of providing i18n support. This hinders e.g. the adaption by users in non-English speaking communities.

## Decision Drivers

1. Reliability (are the selected tools popular and maintained?)
1. Integration (are the selected tools straightforward to integrate into the our existing tools and services?)
1. Simplicity (are the selected tools easy to use?)
1. Code readability (is the produced code easy to understand?)
1. Standardisation (do the selected tools adhere to available standards?)
1. Financial cost (are the selected tools inexpensive to use?)

It needs to be distinguished between changes of dropapp, v2, and/or external services such as Auth0.

### dropapp

In dropapp translation of text has been adopted in some cases inside a table for translation. The issue with this approach is that for every translation a query is required to get the text.

Translations exist for French and Dutch, along with the default English.

Using a browser-translation tool would remove the need to perform any implementation efforts on this end.

User settings are currently configured via dropapp, hence we'd have to consider an extension such that users can set their preferred language.

### Auth0

We most likely want to store user preference for a language in the user management system.

### v2

Due to the client-server architecture of the v2 web application, translatable text is defined in the front-end. Most of the rest of this document focuses on finding a suitable tool to integrate into the v2 React front-end.

### Translation management system (TMS)

A TMS supports in managing translations in software, and facilitates cooperation between devs, designers, and translators. Popular open-source solutions are e.g.
- Tolgee (1k texts for free, then €25/mo): https://tolgee.io/apps-integrations/react
- Weblate (free plan for libre projects): https://weblate.org/en/hosting/
- Locize (special offer for open-source projects): https://locize.com/open-source.html

## Considered Options

The two most popular i18n tools for React:

### `react-intl`

- 1.6M weekly downloads from npm
- Uses ICU standard
- Requires custom solution for translation file loading and locale detection
- support for complex plurals, date formatting, and number formatting
- CLI for message extraction and and Translation Management System (TMS) support
- bundled size of 18kB (gzipped and minified)
- supports IE11 & 2 most recent versions of Edge, Chrome, Firefox & Safari
- using react-intl in React Native, make sure your runtime has built-in Intl support

### `react-i18next`

- 3.8M weekly downloads from npm
- built-in locale switcher
- ICU standard and message extraction through addons
- Plugins for async translation file loading and locale detection
- support for complex plurals, date formatting, and number formatting
- Fairly large bundled size of 23kB (gzipped and minified)
- react-i18next is optimally suited for server-side rendering (does not apply to the FE!?)

### Comparison of the APIs

**react-intl**

```javascript
import {FormattedMessage} from 'react-intl';

<FormattedMessage
description="Name introduction" // Description should be a string literal
defaultMessage="My name is {name}" // Message should be a string literal
values={
{
name: userName,
} // Values should be an object literal, but not necessarily every value inside
}
/>
```

**react-i18next**

```javascript
import { useTranslation } from 'react-i18next';

export function MyComponent() {
// not passing any namespace will use the defaultNS (by default set to 'translation')
const { t, i18n } = useTranslation();
return <p>{t('my translated text')}</p>
}
```

## Decision

The presented react-packages are on a par with each other in terms of the decision criteria above.

The resulting code style of each solution is probably subject to individual taste however `react-i18next` is decoupled from React in terms of testability and ease of building tools on top of it.

For `react-intl`, an experimental integration into v2 can be found [here](https://github.com/boxwise/boxtribute/pull/1753).

For `react-i18next`, an experimental integration into v2 can be found [here](https://github.com/boxwise/boxtribute/compare/experiment-with-react-i18next).

Using a TMS might not be worth the additional cost and maintenance effort, given that boxtribute (v2) is a fairly small application.

## Consequences / effort estimation

### Initial steps

**Infrastructure** (20h)
- Install i18n package
- Set up workflow such that newly added text is auto-extracted (warn about missing translation)
- Ensure that translation files are shipped with the deployed FE bundle
- OPTIONAL (extra 20h): integrate TMS (cloud-repo and/or cloud-CI integration)

**Prepare codebase** (50h)
- Find all text components in FE code, and wrap them such that they can be extracted and replaced

**Translation** (20-50h per language; depends on abilities of translator, and potential copying effort)
- Extract messages and actually translate them (into the desired languages)

### Development cycle

- Devs have to remember to wrap new text components to make them translatable
- Translations are best provided during the design phase already
- Translations are entered into the translation storage
- Effective translation updates require a production deploy
- The app should be reviewed in different languages to catch e.g. alignment or overflow glitches

## Open questions

- [Caveat for react-intl compatibility with React-native](https://formatjs.github.io/docs/guides/runtime-requirements#react-native)
- consider localization for displayed numbers (amount, price, date, time, ...)?

## References

https://phrase.com/blog/posts/react-i18n-best-libraries/

https://formatjs.github.io/docs/getting-started/installation#minimal-application
https://github.com/PhraseApp-Blog/react-i18n-libraries-2022/tree/react-intl
https://phrase.com/blog/posts/localizing-react-apps-with-i18next

https://react.i18next.com/guides/quick-start
https://react.i18next.com/guides/the-drawbacks-of-other-i18n-solutions#the-drawbacks
https://react.i18next.com/misc/using-with-icu-format#extend-the-i18n-instance-with-icu-module
https://github.com/i18next/react-i18next/tree/master/example/react
https://www.i18next.com/