https://github.com/loveholidays/phrasebook
A significantly smaller drop in replacement for react-i18next
https://github.com/loveholidays/phrasebook
i18next react react-i18next translation
Last synced: 9 months ago
JSON representation
A significantly smaller drop in replacement for react-i18next
- Host: GitHub
- URL: https://github.com/loveholidays/phrasebook
- Owner: loveholidays
- License: lgpl-3.0
- Created: 2022-03-31T12:18:27.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2025-02-11T02:19:37.000Z (over 1 year ago)
- Last Synced: 2025-09-04T01:49:39.979Z (10 months ago)
- Topics: i18next, react, react-i18next, translation
- Language: TypeScript
- Homepage:
- Size: 1.57 MB
- Stars: 75
- Watchers: 9
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Phrasebook
A lightweight translation library for React/Preact projects with a similar interface to `react-i18next`.
Made with ❤️ by [loveholidays.com](https://www.loveholidays.com)
## Why phrasebook?
- Tree-shakeable
- Similar interface to `react-i18next`
- Native ESM module with TypeScript type definitions
- Small bundle size (~1kb)
This package exports native [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and does not provide a CommonJS export.
## Bundle size comparisons
| Package | Bundle size (gzip) | Difference |
| ------------------------ | ------------------------------------------------------------------ | ---------- |
| @loveholidays/phrasebook | [1.1kb](https://bundlephobia.com/package/@loveholidays/phrasebook) | baseline |
| @lingui/react@4.11 | [1.4kb](https://bundlephobia.com/package/@lingui/react@4.11.4) | + 27% |
| react-i18next@15.0 | [5.3kb](https://bundlephobia.com/package/react-i18next@15.0.2) | + 482% |
## Installation
Currently available on [NPM](https://www.npmjs.com/package/@loveholidays/phrasebook):
```
$ npm i -S @loveholidays/phrasebook
- or -
$ yarn add @loveholidays/phrasebook
```
## Using a dev version of Phrasebook in a dev app
We can use yalc for this, which creates a local store that we can publish and pull dependencies from.
To publish Phrasebook to the local store:
```bash
npx --yes yalc publish
```
In your target repo (eg. sunrise), update the dependency to local Phrasebook:
```bash
npx yalc add @loveholidays/phrasebook
```
If you make a change in your local Phrasebook repo, update the local store and the target repo:
```bash
npx yalc publish --push
```
To reset the dependency of Phraseboook, in your target repo run:
```bash
npx yalc remove @loveholidays/phrasebook
```
## Usage
Use the `TranslationProvider` to create the localisation context:
```tsx
import { TranslationProvider } from '@loveholidays/phrasebook';
const App = () => (
{
const { key, argumentName } = data;
}}
>
// ...
);
```
The `locale` string is used for locale specific number formatting.
The `translations` object follows a format similar to the i18next JSON format [with some exceptions](#differences-to-i18next).
Use the `useTranslation` hook to access the translation function:
```tsx
import { useTranslation } from '@loveholidays/phrasebook';
const MyComponent = () => {
const { t } = useTranslation();
return (
<>
{t('helloWorld')}
{t('welcomeBack', { name: 'David' })}
{t('youHaveXNewMessages', { count: 14 })}
>
);
};
```
Use the `Translation` component to embed React components into the translations (similar to the [Trans component](https://react.i18next.com/latest/trans-component) of `react-i18next`):
```tsx
import { Translation } from '@loveholidays/phrasebook';
const MyComponent = () => (
here1>, served by: <2>"
params={{
count: 1234,
}}
components={[
(text) => {text}, // text between <1> and 1> is passed in as a param
,
]}
/>
);
// result:
Read all the 1234 reviews here, served by: 
```
## Differences to i18next
The goal is to provide a lightweight alternative for the most common used features of `react-i18next`, although phrasebook won't ever be 100% compatible with that.
- There is no support for [translation backends](https://www.i18next.com/how-to/add-or-load-translations#combined-with-a-backend-plugin), the translation object must be loaded and passed in to the `TranslationProvider`.
- The translation object format is not fully compatible with the [i18next JSON format](https://www.i18next.com/misc/json-format), the currently supported features are: nested translations, `_plural` suffix, [contexts](https://www.i18next.com/translation-function/context#basic).
## Namespaces
Namespaced translations can be used with `` by passing an object into the `namespaces` prop - where the keys are the names of the namespaces and the values are the translations for the given namespace:
```tsx
```
The `ns` option controls the namespace when using the `t` function:
```tsx
const { t } = useTranslation();
const homepageTitle = t('title', { ns: 'homepage' });
const checkoutTitle = t('title', { ns: 'checkout' });
```
To avoid repeating the `ns` option when using `t`, the default namespace can be changed when using the `useTranslation` hook:
```tsx
const { t } = useTranslation('homepage');
const homepageTitle = t('title');
const checkoutTitle = t('title', { namespace: 'checkout' });
```
The `Translation` component takes an optional `namespace` prop to achieve the same:
```tsx
```
## i18n ally extension support for VS Code
We highly recommend to use the [i18n ally](https://github.com/lokalise/i18n-ally) extension for VS Code users. To make it work with phrasebook you need to add this file to your project:
```yaml
# .vscode/i18n-ally-custom-framework.yml
languageIds:
- javascript
- typescript
- javascriptreact
- typescriptreact
usageMatchRegex:
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
monopoly: false
```
## Contributing
Please see our [contributing guidelines](./CONTRIBUTING.md)