Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ddadaal/react-typed-i18n
A strongly typed i18n library for react
https://github.com/ddadaal/react-typed-i18n
i18n react strongly-typed
Last synced: 22 days ago
JSON representation
A strongly typed i18n library for react
- Host: GitHub
- URL: https://github.com/ddadaal/react-typed-i18n
- Owner: ddadaal
- License: mit
- Created: 2021-06-04T08:40:31.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-06-08T01:16:54.000Z (over 1 year ago)
- Last Synced: 2024-10-08T16:36:48.048Z (about 1 month ago)
- Topics: i18n, react, strongly-typed
- Language: TypeScript
- Homepage:
- Size: 2.48 MB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
react-typed-i18n
![npm](https://img.shields.io/npm/v/react-typed-i18n)
[![Build and Test](https://github.com/ddadaal/react-typed-i18n/actions/workflows/build.yml/badge.svg)](https://github.com/ddadaal/react-typed-i18n/actions/workflows/build.yml)
[![Coverage Status](https://coveralls.io/repos/github/ddadaal/react-typed-i18n/badge.svg?branch=master)](https://coveralls.io/github/ddadaal/react-typed-i18n?branch=master)
A strongly typed i18n library for react.![Demo](docs/demo.gif)
# Install
```
npm install --save react-typed-i18n
```# Features
- **Typechecked** text id using TypeScript's [Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html)
- **Interpolation** with `string` and `React.ReactNode`
- **Async language loading** for code splitting
- **Hot language reloading** without reloading page
- No external dependency and **1.3 KiB** gzipped
- **100%** line and branch test coverageThis library is the successor of [`simstate-i18n`](https://github.com/ddadaal/simstate-i18n). Most concepts and functionalities remain unchanged, but this library
- removes the [`simstate`](https://github.com/ddadaal/simstate) dependency
- use Template Literal Types to typecheck the text id
- is way easier to setup# Example
My personal website [ddadaal.me](https://ddadaal.me) is built with this library.
A example project is provided under the `example` folder. Run the following commands to run it.
```bash
# On the library project root
npm install
npm run build
cd example
npm run dev
```# Usage
1. Define your definitions (one file per language)
- use `{}` as a placeholder for interpolation
- object can be nested
- all languages should have identical structures
- this object is called `Language````tsx
// ./src/i18n/en
export default {
hello: {
world: "Hello {} World {}",
}
}// ./src/i18n/cn
export default {
hello: {
world: "你好 {} 世界 {}",
}
}
```2. Define all your languages and create elements from `createI18n`
- The key of `languages` is the **id** of the language;
- The value of `languages` is `Language` or `() => Promise`
- Use `languageDictionary` helper to create the initialization arg
```tsx
// ./src/i18n/index.ts
import { createI18n, languageDictionary } from "react-typed-i18n";const cn = () => import("./cn").then((x) => x.default);
const en = () => import("./en").then((x) => x.default);export const languages = languageDictionary({
cn,
en,
});export const { Localized, Provider, id, prefix, useI18n } = createI18n(languages);
```3. Wrap the component tree with `Provider` component
- A `Language` object and its corresponding id must be provided for the `Provider` compoennt
- In some circumstances (like SSR), rather than importing `Language` directly, `Language` can be asyncly loaded and provided.```tsx
// ./src/Root.tsx
import React from "react";
import en from "./i18n/en";
import { Provider } from "./i18n";
import App from "./App";export default () => {
return (
);
}
```4. Use `Localized` in places of raw texts
- Use `args` prop to interpolate args into the placeholders
- A type error will be reported if the id is not valid
- The `Localized` must be imported from where the `createI18n` is called (for example, `./src/i18n`)
- The below displays: Hello **AAA** World **BBB**```tsx
// ./src/App.tsx
import React from "react";
import { Localized } from "./src/i18n";export default () => {
return (
AAA,
BBB,
]}
/>
);
}
```5. Use `useI18n` hook to get helper functions like `setLanguageById`
- After clicking the button, the p will display: 你好 **AAA** 世界 **BBB**```tsx
// ./src/App.tsx
import React from "react";
import { Localized, useI18n } from "./src/i18n";export default () => {
const { setLanguageById } = useI18n();
return (
AAA,
BBB,
]}
/>
setLanguageById("cn")}>
Change to cn
);
}
```# Helpers
## Helpers functions to generate text id
```tsx
import { prefix, id } from "./i18n";// id is just an identity function with typecheck
const i = id("hello.world"); // id === "hello.world"// prefix generates a prefix function.
// When the function is called,
// two part are concatenated.
// both part are typechecked.
const p = prefix("hello.");
const fullId = p("world");
```## All ids type
```tsx
// src/i18n/en.ts
export default {
a: "a",
b: {
c: "c",
},
};// src/i18n/index.ts
import { TextIdFromLangDict } from "react-typed-i18n";// "a" | "b.c"
export type TextId = TextIdFromLangDict;
```# License
MIT