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 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-router-i18n

v1.1.1

Published

Opinionated internationalization (i18n) library using React Router

Downloads

6,149

Readme

React Router I18n

This is a small opinionated library for I18n (internationalization) using React Router.

Demo

https://zfletch.github.io/react-router-i18n/

Installation

yarn add react-router-i18n

Note that this package has the following peer dependencies:

{
  "react": "^16.8.4",
  "react-dom": "^16.8.1",
  "react-router-dom": "^4.3.0 || ^5.0.0"
}

(See project on npm)

How to use

Demo

See the demo App.js and I18n.js.

Setup

First, create a component called I18n. It should look like this:

import { createI18n } from 'react-router-i18n';

// Array of supported locales
// The first in the array is treated as the default locale
const locales = ['en', 'fr'];

// Dictionary of translations
const translations = {
  en: {
    hello: 'Hello',
  },
  fr: {
    hello: 'Bonjour',
  }
}

const I18n = createI18n(
  locales,
  translations,
);

export default I18n;

Then make the following changes to your routes:

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

// Match locales with regular expression containing each locale separated by `|`
const base = '/:locale(en|fr)?';

const App = () => (
  <Router>
    <>
      {/* <Route exact path="/" component={Home} /> */}
      <Route exact path={base} component={Home} />

      {/* <Route path="/hello" component={Hello} /> */}
      <Route path={`${base}/hello`} component={Hello} />
    </>
  </Router>
);

export default App;

Usage

Once you have everything set up, you can use the I18n component for localization:

import React from 'react';

import I18n from './I18n';

const Hello = () => (
  <div>
    <I18n t="hello" />
  </div>
)

export default Hello;

Since we defined "hello" in the translations object above, this component will display "Hello" when the user visits /hello, or /en/hello. It will display "Bonjour" when the user visits /fr/hello.

Links

To preserve the locale in links, the library provides Link, NavLink, and Redirect components. These can be used anywhere the React Router component with the same name is used:

import React from 'react';
import { Link, NavLink, Redirect } from 'react-router-i18n';

import I18n from './I18n';

const Hello = () => (
  <div>
    <I18n t="hello" />

    <Link to="/">
      <I18n t="homepage" />
    </Link>
  </div>
);

export default Hello;

To create a link that does not preserve the locale, use ignoreLocale:

import React from 'react';
import { Link, NavLink, Redirect } from 'react-router-i18n';

import I18n from './I18n';

const Hello = () => (
  <div>
    <I18n t="hello" />

    <NavLink ignoreLocale to="/en/hello">
      English
    </NavLink>
    <NavLink ignoreLocale to="/fr/hello">
      French
    </NavLink>
  </div>
);

export default Hello;
Note

A Link must be used inside of a route that receives the locale param. For example:

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Link } from 'react-router-i18n';

const base = '/:locale(en|fr)?';

const App = () => (
  <Router>
    <>
      {/* This will not work because it does not receive `locale` */}
      {/* <Link to="/home">Home</Link> */}

      {/* Use code like this instead */}
      <Route path={base} render={() => <Link to="/home">Home</Link>} />

      <Route exact path={base} component={Home} />
      <Route path={`${base}/hello`} component={Hello} />
    </>
  </Router>
);

export default App;

Other functionality

Nested translations

The translations object can have objects inside of it. For example:

const translations = {
  en: {
    home: {
      title: 'Home',
    }
  },
  fr: {
    home: {
      title: 'Accueil',
    }
  },
};

These can be used by giving the I18n component t="home.title":

<I18n t="home.title" />
Function translations

The translations object can have a function as the translation. For example:

const translations = {
  en: {
    time: ({ hour, minute }) => `${hour}:${minute}`,
  },
  fr: {
    time: ({ hour, minute }) => `${hour}h${minute}`,
  },
};

An argument can be passed to the function by giving the I18n component args:

<I18n t="time" args={{ hour: '12', minute: '30' }}  />
Translations outside of <I18n>

Translation text can also be retrieved outside of an I18n component using the getTranslation function. For example:

const translations = {
  en: {
    search: 'Search...'
  },
  fr: {
    search: 'Rechercher...',
  },
}
const { location } = this.props;

<input placeholder={I18n.getTranslation(location, 'search')} />

Note that location needs to be passed in as the first argument. The location prop is passed to a component from React Router.

The getTranslation function takes an optional third argument that corresponds to the args attribute of the I18n component:

const { location } = this.props;

<input placeholder={I18n.getTranslation(location, 'time', { hour: '12', minute: '30' })} />
Default translation

If there is no translation found for the given locale, the library will look in the following places:

  1. The same t in the default locale (i.e. the first locale in the locales array).
  2. The children of the <I18n> component.
  3. The missingText passed to the createI18n function. By default this is false, so if no translation text is found, the <I18n> component will simply not render.

For example, given the following I18n component:

import { createI18n } from 'react-router-i18n';

// Array of supported locales
// The first in the array is treated as the default locale
const locales = ['en', 'fr'];

// Dictionary of translations
const translations = {
  en: {
    hello: 'Hello',
  },
  fr: {
    goodbye: 'Au revoir',
  }
};

const I18n = createI18n(
  locales,
  translations,
  'Unknown text',
);

export default I18n;

Used in this way:

<>
  <I18n t="hello" />
  <I18n t="goodbye">
    Goodbye
  </I18n>
  <I18n t="other" />
</>

The page when viewed with /fr will show:

Hello
Au revoir
Unknown text

With /en it will show:

Hello
Goodbye
Unknown text

Development

Installation

yarn install

Running tests

yarn test

Running demo application

yarn start

Deploying demo application

yarn deploy

Building

yarn build

Publishing

yarn build
npm publish

(Make sure to update the version in package.json before publishing a new release.)

Upgrading Notes

This library is build on top of DimiMikadze/create-react-library. To upgrade to the latest version of create-react-library:

  • In package.json, everything above devDependencies should not be updated, but everything below it should be replaced by the new versions in create-react-library.
  • Add back the dependencies for the project
  • All of the files in ./scripts should be replaced with new versions in create-react-library.
  • All of the files in ./config should be replaced with new versions in create-react-library.
  • Test to make sure that building and deploying demo application still work