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

@serus/i18n

v0.1.92

Published

Internationalization helper

Downloads

3

Readme

i18n

Internationalization helper

JavaScript Style Guide Build Status

Install

yarn add @serus/i18n

Overview

Roadmap

  • initialLocale helper
  • todo optimise default translations
  • docs
  • i18next plugin
  • WTI plugin
  • PhraseApp plugin
  • enable use key context !!TBD

Usage

This library supports only JSX format (because of context). If you need to have access to string typed value, use Render props or I18n.toString(<I18n ... />)

Common usage

import * as React from 'react';
import I18n from '@serus/i18n';

class Example extends React.Component {
  render() {
    return <I18n id="id1" d="Hello World!" />;
  }
}

Render props

<I18n id="id1" d="Hello World!">
  {placeholder => <input placeholder={placeholder} />}
</I18n>

I18n.toString()

this helper using ReactDOM to stringify component, but for consistent translation we need to have I18nContext available, so:

const placeholder = I18n.toString(<I18n id="key1" d="Defaut message" />);
console.log(typeof placeholder); // string

Context provider

Simple react context provider which enables you modularize your translations for each part separately (you neet to keep your current locale on your own, just pass locale property to provider)

import * as React from 'react';
import I18n, { Provider as I18nProvider } from 'i18n';

class App extends React.Component {
  render() {
    return (
      <I18nProvider locale="en">
        <I18n id="id1" d="Hello World!" />
      </I18nProvider>
    );
  }
}

Translation source

Best practice for internationationalization SPA is to serve translated app (per domain / per client locale accept-language header / ip pool / country / brand / etc. )

This lib supports production build with custom translation replaced right in js files (default localization is available instantly). Babel plugin will replace "default" messages and if user dont change his lang, app is delivered in right language as fast as possible.

In other case, we need to load translation, mostly in async mode because if server dont know which lang shoud be serverd, it will serve all supported languages and this behavior have negative inpact for page load speed.

So as a result internationalization provider expects Promise as source input (dynamic) dependency / code split / using cloud language tool wtc.)

Common usage

  import { Provider, sourceFactory } from 'i18n';

  const sourceMap = {
    // static json
    en: () => Promise.resolve({ key1: 'Val 1' }),
    // use dynamic import a.k.a code split
    sk: () => import('../i18n/sk.json').then(module => module.default)
  }

  const translationSource = sourceFactory(sourceMap);

  <Provider locale="en" source={translationSource}>

Each promise will be fired once, and in time when needed.

Custom

You can implement your own localization resolver, expected interface is map of resolvers for each locale, get & match so:

const enSource = { ke1: 'Translated text' };
const skSource = { key1: 'Prelozeny text' };

{
  en: {
    get: (key: string) => enSource[key];
    match: (search: string) => enSource; // *
  },
  sk: {
    get: (key: string) => skSource[key];
    match: (search: string) => skSource; // *
  }
}

* match exists for ENUM keys

Enums

custom feature of this lib is enum key handling. Imagine, if you have some dynamic context like response message which depends on Promise response value, so you can put

const result = 'err1'
<I18n
  d={{ done: "Wohoo!", err1: "Oops!", err2: "Yayy!" }}
  id="enumMsg$"
  v={result}
  />

those keys must endsWith $ & have d defined as object & must pass v parameter

if you use enum keys, match resolver will be applied, so you can search any keys by your own rules, or by default, in case of render props usage, all keys which starts with %d%$ will be computed into single object by default match handler and passed as second parameter of render props

Render props

<I18n
  d={{ done: "Wohoo!", err1: "Oops!", err2: "Yayy!" }}
  id="enumMsg$"
  v={result}
>
  {(value, object) => <>
    value: {value}
    all values:
    <pre>{JSON.stringify(object, null, 2)}</pre>
  </>}
</i18n>

License

MIT © serus22