npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

reactive-i18n

v1.0.2

Published

Internacionalization to your components. Supporting multiple dictionaries, global contents, variables, plural and singular, among other features

Readme

Reactive I18N

Reactive-i18n allows you to, reactivelly, deal with Internacionalization in your pages and apps.

With it, you create multiple dictionaries and use them in your components in a very, very ease, intuitive, readable and mantainable way. It even works with plurals, variables, lists and fallbacks.

See it working in this live demo. And see its source here

Installing it

npm install reactive-i18n

Importing it

First, you import both I18N and Label

import I18N, { Label } from 'reactive-i18n'
// OR
import { I18N, Label } from 'reactive-i18n'

Then, you may import your dictionaries (to be descibre in chapter Dictionaries):

import myDictionary from './my-dictionary.js'

You may use as many as you want.

Scope

You may specify a given scope for making use of a dictionary or language, like so:

    [...]
    render() {
        return <I18N
        use={myDictionary}
        lang={this.state.lang}>
            // your content goes here
        </I18N>
    }
    [...]

If you have more dictionaries to be used in the same scope, simply pass an Array in the use property.

Terms

Inside any scope, you may use the Label.

    [...]
    render() {
        return <I18N
        use={myDictionary}
        lang={this.state.lang}>
        <div>
            [...]
            <Label term='UserNameAndSurname' />
            [...]
        </div>
        </I18N>
    }
    [...]

It will look for the term UserNameAndSurname in all the dictionaries in the current scope, that bes match with the lang in the current scope.

Interestingly enough, a warning will be shown when a term is not found. But also, the term will be treated before being shown on the screen. The example above would become User name and surname...not translated, but better for users in case you forgot to translate any term in your dictionaries.

Dictionaries

Dictionaries are just an object.
They have an id, a langs object and may have a version.

const dictionary = {
    id: 'myDictIdentifier',
    version: '1',
    langs: {
        // ...
    }
}
export default dictionary

Dictionary's langs

This is an object containing all the languages you will support, and each language, all the terms, like this:

const dictionary = {
    id: 'myDictIdentifier',
    version: '1',
    langs: {
        en: {
            UserNameAndSurname: 'Full name'
        },
        es: {
            UserNameAndSurname: 'Nombre completo'
        }
    }
}
export default dictionary

And that is it. This is the basic usage.

Plural and singular

If you want to use different strings for plural or string, first, you need to say the number. You do that using the val property:

    <Label
        term='friends'
        val={this.state.groceries.length} />

And, in the dictionary, you simple use an array with 2 strings, instead of one:

    // ...
    langs: {
        en: {
            friends: [
                'Friend',
                'Friends'
            ]
        },
        es: {
            friends: [
                'Amigo',
                'Amigos'
            ]
        }
    }
    // ...

Variables

You can send some variables, and use them as in template strings, with the ${varName} syntax.
Send variables like this:

    <Label
        term='hi'
        person={'Felipe'} />

In dictionary, you can now access person:

    // ...
    langs: {
        en: {
            hi: 'Hi ${person}'
        },
        es: {
            hi: 'Hola ${person}'
        }
    }
    // ...

Lists

You can send lists, as well.

    <Label
        term='friends'
        friends={['Felipe', 'Jaydson', 'Gabe']} />

In dictionary:

    // ...
    langs: {
        en: {
            friends: 'Hi ${friends}'
        },
        es: {
            friends: 'Hola ${friends}'
        }
    }
    // ...

By default, all the items in the list will be glued by , .
BUT...you can change that by specifying the joints in your dictionary:

    // ...
    langs: {
        en: {
            joints: [', ', ' and ', ' or '],
            friends: 'Hi ${friends}'
        },
        es: {
            joints: [', ', ' y ', ' o '],
            friends: 'Hola ${friends}'
        }
    }
    // ...

Now, the output in english would be Hi Felipe, Jaydson and Gabe, and the output in spanish would be Hola Felipe, Jaydson y Gabe.

Change the jointType to get the or.

    <Label
        term='friends'
        jointType='or'
        friends={['Felipe', 'Jaydson', 'Gabe']} />

The jointType may be or, and (default) or none (will use only ,)

You may even combine plural with your variables:

    <Label
        term='friends'
        val={this.state.friends.length}
        friends={this.state.friends} />

And, in dictionary:

    // ...
    langs: {
        en: {
            joints: [', ', ' and ', ' or '],
            friends: [
                'Hello my only friend, ${friends}',
                'Hello all my ${val} friends ${friends}'
            ]
        },
        es: {
            joints: [', ', ' y ', ' o '],
            friends: [
                'Hola mi único amigo, ${friends}',
                'Hola mis ${val} amigos ${friends}'
            ]
        }
    }
    // ...

Global / World

You may define some global terms...something that all (or most) of languages share in common.

For exampe:

    <Label
        term='dateFormat'
        day={19}
        month={'07'}
        year={1985} />
    // ...
    langs: {
        world: {
            dateFormat: '${day}/${month}/${year}'
        },
        'en-US': {
            dateFormat: '${month}/${day}/${year}'
        }
    }
    // ...

Different files for each language

Once the scope accepts multiple dictionaries, you can simply add different dictionaries there, each one, containing a single language.

    [...]
    render() {
        return <I18N
        use={[myEnDict, myEsDict, myPtDict]}
        lang={this.state.lang}>
            // your content goes here
        </I18N>
    }
    [...]

Fallback language

By default, it will follow this pattern.
If you specify the lang pt-BR, it will look for the terms there.
If the term is not found, then looks for it in any dictionary in pt.
If not found yet, looks for it in world.

But you may specify the fallbackLang for the scope, changing the behavior of the second step.

    [...]
    render() {
        return <I18N
        use={[myEnDict, myEsDict, myPtDict]}
        lang='pt-BR'
        fallbackLang='en'>
            // ...
        </I18N>
    }
    [...]

The fallbackLang property also accepts none. In this case, if the term is not found in any dictionary, no worning will be triggered and will not show anything on the screen for that term.

Technical table

Component

In your react components:
(* means mandatory)

| Element | Prop | Val | | ------------- |----------------|-----------------| | | use* | Object or array | | | className | A className, so you can customize it | | | lang* | String, the language itself, like en or en-US | | | fallbackLang | String, the language to be used as fallback, like en or en-US If none, the string will be ommited in case it was not found in any dictionary | | | className | A className, so you can customize it | | | term* | The term to be found in dictionaries | | | val | Used to decide if it is plural or singular | | | jointType | Used to know how to join lists with their last item. May be 'and', 'or' or 'none (default is 'and') | | | anyOtherProp | Any other property will be passed to be used as variables |

Dictionary

In your dictionaries:
(* means mandatory)

| Element | Prop | Val | | ------------- |----------------|--------------------------| | DictionaryObj | id* | An id for the dictionary | | DictionaryObj | version | A version for the dictionary | | DictionaryObj | langs | The languages object containing the languages and their terms | | | langs | world | A fallback for terms not found specialized in other languages. May be used for shared terms | | langs | langId | Any language id, like en or en-US. Its value must be an Object | | langObject | joints | An array with three items: the coma, the and and the or representations for lists| | langObject | terms | May be a String for that term in the given language, or an Array with two items, the first for the singular value, the second for the plural representation of the value |