Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fakundo/react-localized

Internationalization for React and Preact components based on gettext format
https://github.com/fakundo/react-localized

gettext i18n internationalization preact react

Last synced: 29 days ago
JSON representation

Internationalization for React and Preact components based on gettext format

Awesome Lists containing this project

README

        

# react-localized / preact-localized

[![npm](https://img.shields.io/npm/v/react-localized.svg)](https://www.npmjs.com/package/react-localized)
[![npm](https://img.shields.io/npm/v/preact-localized.svg)](https://www.npmjs.com/package/preact-localized)

Complete internationalization tool for React and Preact components.

Features:

- based on [gettext](https://www.gnu.org/software/gettext/manual/gettext.html) format, uses translation `.po` files

- translation strings for `.po` files can be extracted automatically from project source files

- plural forms are supported

- gettext function aliases are supported

- JavaScript string templates are supported

- locale data is extendable, for example by adding date formats, currencies, etc.

- locale data can be separated from the main bundle by using dynamic import

### Basic component example

```js
import { useLocales } from 'react-localized' // or from 'preact-localized'

export default () => {
const { gettext } = useLocales()
return (
<>
{ gettext('Hello, World!') } // Привет, Мир!
>
)
}
```

### Complex example

[Live demo](http://fakundo.github.io/react-localized/)
|
[Source](https://github.com/fakundo/react-localized/tree/master/examples)

### Installation and usage

#### 1. Use existing `.po` files with translation messages or generate them from your project source files

To generate `.po` files you can use the extractor CLI tool. Extractor searches your project source files for functions like `gettext`, `ngettext`, etc. Extractor also can update existing `.po` files without erasing existing translations in those files.

```console
npm i react-localized-extractor
```

```console
react-localized-extractor [options]

Options:
--version Show version number [boolean]
--help Show help [boolean]
--locales, -l List of desired locales (comma separated) [string] [required]
--source, -s Source files pattern
[string] [default: "./src/**/*.@(js|ts|jsx|tsx)"]
--output, -o Output .po files directory [string] [default: "./locales"]
--alias, -a Function alias [string]
--save-pot Should create catalog .pot file in output directory
[boolean] [default: false]
```

```console
react-localized-extractor -l ru
```

#### 2. Modify `.po` files to add / edit translation

Use your favourite editor for `.po` files. I recommend you to use `Poedit`.

#### 3. Import `.po` files into your project by using webpack loader (optional)

The loader transforms the contents of the `.po` files to JSON using `gettext-parser`. Therefore, if you are not using `webpack`, you can generate JSON files using this parser and import them into your project.

```console
npm i react-localized-loader
```

```js
module: {
rules: [
{
test: /\.po$/,
use: 'react-localized-loader'
}
]
}
```

#### 4. Install `react-localized` or `preact-localized`

```console
// for React
npm i react-localized

// for Preact
npm i preact-localized
```

#### 5. Create data object for each locale

Use the `createLocale` function from the package. The first argument is for translation messages taken from `.po` file. The second argument is for extra data such as date formats, currencies, and so on.

Example of the file `ru.js` for russian locale

```js
import { createLocale } from 'react-localized' // or from 'preact-localized'
import messages from 'messages/ru.po'

const extra = { ... }

export default createLocale(messages, extra)
```

#### 6. Render provider component

```js
import { LocalizedProvider } from 'react-localized' // or from 'preact-localized'

import fr from 'fr.js'
import de from 'de.js'

const ru = () => import('ru.js').then(data => data.default) // separated from the main bundle

const locales = { fr, de, ru }

export default () => (

{ ({ localeReady }) => (
localeReady
? 'render children'
: 'loading locale'
) }

)
```

#### 7. Localize components using hook

```js
import { useLocales } from 'react-localized' // or from 'preact-localized'

export default () => {
const { gettext, ngettext, ...extra } = useLocales()
return (
<>
{ gettext('Hello, World!') } // Привет, Мир!
{ ngettext('apple', 'apples', 1) } // яблоко
{ ngettext('apple', 'apples', 2) } // яблока
{ ngettext('apple', 'apples', 5) } // яблок
>
)
}
```

#### 8. Localize components using HOC (Higher-Order Component)

```js
import { withLocales } from 'react-localized' // or from 'preact-localized'

class LocalizedComponent extends Component {
render() {
const { pgettext, formatDate, formats } = this.props // 'formatDate' and 'formats' are extra data passed to the 'createLocale'
return (
<>
{ pgettext('Context', 'Text with context') } // Текст с контекстом
{ formatDate(new Date(), formats.date) } // 1 января 2020
>
)
}
}

export default withLocales()(LocalizedComponent)
```
### Using string templates

```js
import { useLocales } from 'react-localized' // or from 'preact-localized'

export default () => {
const { gettext, ngettext, pgettext, npgettext } = useLocales()
const name = 'Anna'
const i = 2
return (
<>
{ gettext`My name is ${name}` } // Мое имя Anna
{ ngettext`${i} apple``${i} apples`(i) } // 2 яблока
{ pgettext('Ctx')`My name is ${name}` }
{ npgettext('Ctx')`${i} apple``${i} apples`(i) }
>
)
}
```

### Using function aliases

Use `LocalizedProvider` `alias` prop to define function aliases.

Example of alias for `gettext` only

```js

```

Example of aliases for `gettext` and `ngettext`

```js

```

Example of alias usage

```js
import { useLocales } from 'react-localized' // or from 'preact-localized'

export default () => {
const { __, __n } = useLocales()
const name = 'Anna'
return (
<>
{ __('Hello, World!') }
{ __`My name is ${name}` }
{ __n`apple``apples`(5) }
>
)
}
```

Also configure extractor.

Example of alias for `gettext` only

```console
react-localized-extractor -l ru -a __
```

Example of aliases for `gettext` and `ngettext`

```console
react-localized-extractor -l ru -a.gettext __ -a.ngettext __n
```

### API

#### LocalizedProvider props

- `locales` - defined locales
- `selected` - selected locale (default `en`)
- `alias` - function aliases (string or object)
- `children({ localeReady })`

#### Data returned by hook / props passed to the child of the HOC

- `locale`
- `gettext(text)`
- `ngettext(text, textPlural, n)`
- `pgettext(context, text)`
- `npgettext(context, text, textPlural, n)`
- `...aliases` - defined function aliases
- `...extra` - extra data passed to the `createLocale`

### License

MIT