• Stars
    star
    133
  • Rank 264,275 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

📙 React translation library with plain objects as dictionaries

React Text npm install react-text test badge gzip size

React and React Native translation library with plain objects as dictionaries:

import Text from 'react-text';
import dictionary from './dictionary';

export default () => (
  <Text language="ja" dictionary={dictionary}>
    <p><Text greetings /></p>
    <p><Text farewell name="Francisco" /></p>
  </Text>
);
// <p>こんにちは、世界!</p>
// <p>さよなら、FRANCISCOさん!</p>

Contents:

  • Getting started: Introduction to how to start using react-text with React.
  • Dictionary: define the translations and some basic transformations.
  • Configuration: set the language and inject the dictionary.
  • Translate: use <Text> with a id to create translations with optional properties.
  • Render: inject a translated string into a React component. Useful for alt={} and similar.
  • Component: renders only for the right language.

Getting started

First let's install the package with npm:

npm install react-text

Then we define a dictionary of the text to translate:

// ./dictionary.js
export default {
  greetings: {
    en: 'Hello world!',
    es: '¡Hola mundo!',
    ja: 'こんにちは、世界!'
  }
};

To use those, we need to create a wrapping <Text> with two options: the dictionary and the language. Then inside it, we create a self-closing <Text /> tag with the property as the previously defined key of the object:

// ./Example.js
import Text from 'react-text';
import dictionary from './dictionary';

export default () => (
  <Text language="es" dictionary={dictionary}>
    <p><Text greetings /></p>
  </Text>
);
// ~> ¡Hola mundo!

Dictionary

The dictionary is defined as an object of objects. The first level (greetings) is what we call the id, the second is the language (en) and finally we have the values (Hello world and functions):

// ./dictionary.js
export default {
  greetings: {
    en: 'Hello world!',
    es: '¡Hola mundo!',
    ja: 'こんにちは、世界!'
  },
  farewell: {
    en: ({ name = 'World' }) => `Hello ${name}!`,
    es: ({ name = 'Mundo'}) => `¡Adiós ${name}!`,
    ja: ({ name = '世界' }) => `さよなら、${name.toUpperCase()}さん!`
  }
};

All the languages must be the same in all the entries, otherwise it will throw an error. The order is important as well, since the first language will be considered the default one if it cannot be found otherwise.

Configuration

Once we have the dictionary, we have to determine how and where to inject it, as well as specifying the language. This will be done by creating a <Text> element with children:

import Text from 'react-text';
import dictionary from './dictionary';

export default () => (
  <Text language="en" dictionary={dictionary}>
    {/* Here the language will be English */}
  </Text>
);

For React Native, any of the usual props of <Text>...</Text> can be passed here.

They can be set at different levels, which is specially useful if you want to split the dictionary into different pages:

import Text from 'react-text';
import dictionaryA from './dictionaryA';
import dictionaryB from './dictionaryB';

export default () => (
  <Text language="en">
    <Text dictionary={dictionaryA}>
      {/* English for Dictionary A */}
    </Text>
    <div>
      <Text dictionary={dictionaryB}>
        {/* English for Dictionary B */}
      </Text>
    </div>
  </Text>
);

When nesting dictionaries they will cascade and the latter ids will override the previous ids.

const dictA = {
  greetings: { en: 'Hello world' },
  farewell: { en: 'Goodbye world' }
};
const dictB = {
  greetings: { en: 'Hey world!' }
};

export default () => (
  <Text language="en" dictionary={dictA}>
    <p><Text greetings /></p>
    <Text dictionary={dictB}>
      <p><Text greetings /></p>
      <p><Text farewell /></p>
    </Text>
  </Text>
);
// <p>Hello world</p>
// <p>Hey world!</p>
// <p>Goodbye world</p>

The language would normally be a variable that comes from your own code:

import Text from 'react-text';
import dictionary from './dictionary';

export default ({ language = 'en' }) => (
  <Text language={language} dictionary={dictionary}>
    {/* Here the language will be English */}
  </Text>
);

The language can also be nested, and it will use the most specific (innermost):

const dictionary = { greetings: {
  en: 'Hello world!',
  es: '¡Hola mundo!',
  ja: 'こんにちは、世界!'
}};

export default () => (
  <Text language="en" dictionary={dictionary}>
    <p><Text greetings /></p>
    <Text language="ja">
      <p><Text greetings /></p>
      <Text language="es">
        <p><Text greetings /></p>
      </Text>
    </Text>
  </Text>
);
// <p>Hello world!</p>
// <p>こんにちは、世界!</p>
// <p>¡Hola mundo!</p>

While nesting dictionaries is totally fine and expected, nesting languages might get messy and it's recommended to avoid it if possible. Use a global store like Redux to handle the language instead and inject it at the root level:

// LanguagePicker.js
// Example implementation with Redux and an action creator
const setLanguage = payload => ({ type: 'SET_LANGUAGE', payload });
export default connect(({ language }) => ({ language }))(({ language, dispatch }) => {
  <Text language={language}>
    <button onClick={e => dispatch(setLanguage('en'))}>English</button>
    <button onClick={e => dispatch(setLanguage('es'))}>Spanish</button>
    <button onClick={e => dispatch(setLanguage('ja'))}>Japanese</button>
    <p>Current language: {language}</p>
  </Text>
});

// reducers/index.js
export default combineReducers({
  // ...
  language: (state = 'en', { type, payload }) => {
    return (type === 'SET_LANGUAGE') ? payload : state;
  }
});

Translate

With the dictionary and language injected, use <Text /> with a self-closing tag and the right id:

const dictionary = {
  greetings: {
    en: 'Hello world!',
    es: '¡Hola mundo!',
    ja: 'こんにちは、世界!'
  }
};

// Usage; the prop 'greetings' will correspond to the dictionary id 'greetings'
export default () => (
  <Text language="ja" dictionary={dictionary}>
    <p><Text greetings /></p>
  </Text>
);
// ~> <p>こんにちは、世界!</p>

Valid id names: any prop except id, children, render and component since these have special meaning in React-Text. Click on those keywords to see how they are used. The ids are case-sensitive.

The dictionary can also be a function, which will be called when rendering. The advantage is that it will receive any prop that you pass to the element. You can then localize the text properly depending on the language, and even provide defaults easily:

const dictionary = {
  greetings: {
    en: ({ name = 'World' }) => `Hello ${name}!`,
    es: ({ name = 'Mundo' }) => `¡Hola ${name}!`,
    ja: ({ name = '世界' }) => `こんにちは、${name.toUpperCase()}さん!`
  }
};

// The prop passed as `name` will be received in the dictionary
export default () => (
  <Text language="ja" dictionary={dictionary}>
    <p><Text greetings name="Francisco" /></p>
  </Text>
);
// ~> こんにちは、FRANCISCOさん!

You can also use the id prop instead of just writing the id as a prop. These two work exactly the same:

export default () => (
  <Text language="ja" dictionary={dictionary}>
    <p><Text id="greetings" name="Francisco" /></p>
    <p><Text greetings name="Francisco" /></p>
  </Text>
);

This however works much better for dynamic ids, since those would be messy otherwise:

const key = 'greetings';

export default () => (
  <Text language="ja" dictionary={dictionary}>
    <p><Text id={key} name="Francisco" /></p>
    <p><Text {...{ [key]: true }} name="Francisco" /></p>
  </Text>
);

Note: the props that you can pass can be either strings or numbers, but right now you cannot pass a boolean like <Text greetings isUser={true} />. We might lift this limitation in the future.

Render

Injects the plain text into a function. Useful for those times when you can only pass plain text and not a component:

// These both render to the exact same thing:
<p><Text greetings /></p>
<Text greetings render={text => <p>{text}</p>} />
// ~> <p>Hello world</p>

The next example can only be achieved with render() since it will pass the plain representation as specified in the dictionary:

<Text greetings render={text => <img alt={text} />} />
// ~> <img alt="Hello world">

If you try to do the same with <Text /> you will get an unexpected result, since <Text /> renders a React component:

// ERROR - this does not work as expected
<img alt={<Text greetings />} />
// ~> <img alt="[Object object]">

Component

When trying to do a switch between more complex fragments, or display one part only for one language, we can do so by using the component prop:

<div>
  <Text en component={(
    <section>
      {/* Large block of text in English here */}
    </section>
  )} />
  <Text es component={(
    <section>
      {/* Large block of text in Spanish here */}
    </section>
  )} />
  <Text ja component={(
    <section>
      {/* Large block of text in Japanese here */}
    </section>
  )} />
</div>

Note that, when using component={...}, we are using the language as a key. This would be the internal equivalent of you doing:

// dictionary.js
// NOTE: DO NOT DO THIS, this is just a visualization of how it works internally
export default {
  en: { en: ({ component }) => component, es: '', ja: '' },
  es: { en: '', es: ({ component }) => component, ja: '' },
  ja: { en: '', es: '', ja: ({ component }) => component }
};

More Repositories

1

picnic

👜 A beautiful CSS library to kickstart your projects
CSS
3,772
star
2

server

🖥️ Simple and powerful server for Node.js
JavaScript
3,556
star
3

brownies

🍫 Tastier cookies, local, session, and db storage in a tiny package. Includes subscribe() events for changes.
JavaScript
2,381
star
4

umbrella

☔ Lightweight javascript library for DOM manipulation and events
JavaScript
2,233
star
5

ola

🌊 Smooth animation library for interpolating numbers
JavaScript
1,804
star
6

drive-db

📊 Use Google Drive spreadsheets as a simple database
JavaScript
821
star
7

legally

📚 Check the licenses for the NPM packages that you use
JavaScript
427
star
8

pagex

📄 A simple router for the browser in javascript
JavaScript
332
star
9

superdom

🎏 Better and simpler ES6 DOM manipulation
JavaScript
294
star
10

translate

🈂️ Translate text on node.js and the browser with promises
JavaScript
228
star
11

react-plain-router

🛣 A 2kb React router that works exactly as expected with native Javascript
JavaScript
118
star
12

use-tensorflow

A React hook to use tensorflow.js easily
JavaScript
104
star
13

atama

🌲 State management tool using Proxy()
JavaScript
83
star
14

statux

⚛️ The easy state management library for React with Hooks
JavaScript
71
star
15

swear

🙏 Flexible promise handling with Javascript
JavaScript
57
star
16

use-spreadsheet

A React Hook to use Google Drive spreadsheets as a database
JavaScript
45
star
17

uwork

Tiny webworker that doesn't need an external file to run
JavaScript
44
star
18

cookies

🍪 Delicious browser cookies
JavaScript
42
star
19

react-test

🧯 Make readable assertions for your App and be confident about the code you ship. Reduce user-facing bugs and increase satisfaction.
JavaScript
23
star
20

files

📁 Async filesystem with very simple API for Node.js
JavaScript
23
star
21

use-animation-frame

A React hook to run requestAnimationFrame seamlessly
JavaScript
19
star
22

flexpoint

[discontinued, please use Picnic CSS that includes this ] A breakpoint-based flexbox grid implementation
SCSS
19
star
23

crossroad

🛣 A React library to handle navigation in your WebApp. Built with simple components and React Hooks so your code is cleaner.
JavaScript
18
star
24

vector-graph

Generate high-quality geometry and vector graphs with HTML
JavaScript
16
star
25

tokyochat

Real time chat with socket.io and Node.js
JavaScript
14
star
26

modern-editor

[discontinued] A rich text editor for the modern web
JavaScript
14
star
27

backblaze

An unofficial package to easily deal with Backblaze API on Node.js
JavaScript
13
star
28

form-mate

💬 A tiny and elegant library to handle forms with React
JavaScript
13
star
29

remotecamera

Capture an image and post it to an url
JavaScript
12
star
30

burla

Advanced URL manipulation library using the History API
JavaScript
12
star
31

recordar

A spaced repetition algorithm to analyze several responses from the students and give an approximate score of how much they remember the concept
JavaScript
12
star
32

create-static-web

Another static site generator
JavaScript
11
star
33

fixed-id

A fixed-options export for NanoID using only 24 alphanumeric characters
JavaScript
10
star
34

check-licenses

A simple tool to check all the licenses in your dependencies
JavaScript
10
star
35

happy

Happy simplifies your day-to-day git workflow:
JavaScript
10
star
36

htemplate

A dead simple and tiny template system. Stop repeating yourself.
HTML
9
star
37

use-camera

Stream the native camera video and audio into React
JavaScript
8
star
38

fetch

fetch() greatly improved
JavaScript
8
star
39

edittable

React simple records table with a REST API
JavaScript
7
star
40

use-async

React hooks to make handling async operations a breeze
JavaScript
7
star
41

use-interpolation

A hook to interpolate values easily in React
JavaScript
7
star
42

lobe

Deep learning made easy with Lobe.ai
JavaScript
6
star
43

cloudbleed

Website interface for cloudbleed domain list
HTML
6
star
44

server-tutorial-spreadsheet

Code for the tutorial of spreadsheets
HTML
6
star
45

atocha

Run clean terminal commands from Node.js
JavaScript
6
star
46

human-error

Allows you to write errors so people can understand
JavaScript
5
star
47

sign

A universal javascript library for signing strings to avoid tampering
JavaScript
5
star
48

json-ok

A quick way of validating json objects using json-schema
JavaScript
5
star
49

red-arrow

Draws a red arrow in React
JavaScript
5
star
50

spacehelmet

Space Apps contest
Processing
5
star
51

paperdocs

📄 A beautiful and highly responsible theme for documentation
JavaScript
5
star
52

travel

Javascript-based CRUD ORM for varied sources
JavaScript
4
star
53

json-chaos

A tool that randomly changes properties in objects
JavaScript
4
star
54

express-data-parser

Middleware to parse images and files with express
JavaScript
4
star
55

server-tutorial-todo

Code for the TODO tutorial
JavaScript
3
star
56

use-storage

A React Hook to handle localStorage properly in your WebApp
JavaScript
3
star
57

pray

React asynchronous components
JavaScript
3
star
58

server-next

Experiment around server.js
JavaScript
3
star
59

faster

Tiny function to repaint into a canvas in fullscreen mode
JavaScript
3
star
60

poly-get

A tiny fetch() universal library for getting JSON
JavaScript
3
star
61

react-press

⏎ Easily handle key press events with React
JavaScript
3
star
62

react-simple-keys

A simple and straightforward shortcut/hotkeys hook handler for React
JavaScript
3
star
63

test-controller

Testing module for the controllers. Extends req and res from dupertest
JavaScript
3
star
64

basik

A component library for React that looks great out of the box
JavaScript
2
star
65

xlsx-demo

A demo of using drive-db and xlsx
JavaScript
2
star
66

check-my-links

A small CLI tool to make sure your website doesn't have any 404s or 500s
JavaScript
2
star
67

files-api

Official documentation for https://files-api.com/
2
star
68

server-sass

A small plugin to handle SASS and SCSS with server.js
JavaScript
2
star
69

anchor

Spaced repetition program
HTML
2
star
70

readline-polyfill

Readline polyfill using only `node:events` and `node:tty`
JavaScript
2
star
71

orden

Parse a markdown table string into an array of objects. With types! Perfect to mock data.
JavaScript
2
star
72

react-tokyo

JavaScript
2
star
73

UserManager

User management system.
PHP
2
star
74

loadware

Make sense of a bunch of middleware definitions and return an array of middleware
JavaScript
2
star
75

todo

Some times you just want to finish a project, no matter how tiny it is :)
JavaScript
2
star
76

premonition

Premonition
HTML
2
star
77

blog

A dead simple Drive based blog
JavaScript
1
star
78

azalea

Web de azalea
CSS
1
star
79

optionally

Option parser with schema definition and descriptive errors
JavaScript
1
star
80

japan-rent-calculator

HTML
1
star
81

transladb

PHP translation class database-driven.
PHP
1
star
82

pipas

Web and Node streams quick experiment
JavaScript
1
star
83

server-bug127

Repro repo
HTML
1
star
84

nocolor

A tiny library to color your terminal output
JavaScript
1
star
85

insensitive

A library to make working with case-insensitive (including snake and similar) much easier
JavaScript
1
star
86

franciscop.github.io

My personal website
HTML
1
star
87

photos

Basic image upload service
JavaScript
1
star
88

server-auth

Server.js plugin to handle authentication with Github and Twitter
JavaScript
1
star
89

repository

One click website for your Github repos
1
star
90

server-react

React server
JavaScript
1
star
91

server-tutorial-upload

Upload images with server.js
JavaScript
1
star
92

server-esm

A server.js plugin to automatically bundle front-end Javascript
JavaScript
1
star
93

add-subs

Add subtitles to an MP4 from a SRT file
JavaScript
1
star
94

chat

Demo for the interview
JavaScript
1
star