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

@owja/i18n

v1.0.0-alpha.9

Published

lightweight internationalization library for javascript

Downloads

345

Readme

OWJA! i18n

npm version codecov Build Status size

This is a lightweight internationalization library which is in early alpha state. This means it is work in progress, unstable, can contain bugs and the API can change until first stable release.

Features

  • lightweight bundle size ~1 kb (brotli compressed, without plugins)
  • no global state
  • it is made with dependency injection in mind
  • Build-in support for plurals, interpolation and context
  • uses Intl.Locale and Intl.PluralRules under the hood
  • Extendable with plugins
What does it not have and why?
  • No loading mechanism. Nowadays we have dynamic imports and fetch and both can do this job perfectly
  • No namespaces. You can add translations while runtime without the need for namespaces If you want some kind of namespaces you can use multidimensional objects
  • No nesting. Could be implemented with a plugin
  • No objects, no arrays
  • No formatting. Could be implemented with a plugin

Extendability (Plugins)

There will be a few plugins on stable release. Planed are:

  • [done] Datetime Formatter, like [[date|1558819424|short]] to 05/25
  • [done] Currency Formatter, like [[cur|2.323122]] to € 2,32
  • [done] Number Formatter, like [[number|2.323122|2]] to 2,32
  • [todo] Html2Char Converter, for some useful codes like ­ to 0x00AD

The reason why this functionality isn't included in the main bundle is that in many cases they are not needed, or you need only one or two and not all.

Usage

Step 1 - Creating an instance of the Translator
import {Translator} from "@owja/i18n";
const translator = new Translator({default:"de",fallback:"en"});

If you use a dependency injection tool, you can bind the .t() method of the translator constant to make accessing the main functionality as easy as possible.

Step 2 - Importing Translations

a) Adding with static imports

import de from "lang/de.json";
import en from "lang/de.json";

translator.addResource("de", de);
translator.addResource("en", en);

b) Adding with dynamic imports

import("lang/de.json").then((m) => translator.addResource("de", m.default));
import("lang/en.json").then((m) => translator.addResource("en", m.default));

c) Adding with fetch

fetch("lang/de.json").then(r => r.json())
    .then((r) => translator.addResource("de", r));
    
fetch("lang/en.json").then(r => r.json())
    .then((r) => translator.addResource("en", r));
Step 3 - Translate something

lang/de.json

{
  "hello": "Hallo Welt",
  "car": "Auto",
  "car_other": "Autos",
  "employee_male_0": "Kein Mitarbeiter",
  "employee_male_one": "Der Mitarbeiter",
  "employee_male_other": "Die Mitarbeiter",
  "employee_female_0": "Keine Mitarbeiterinnen",
  "employee_female_one": "Die Mitarbeiterin",
  "employee_female_other": "Die Mitarbeiterinnen",
  "dashboard": {
    "button": "Ok"
  },
  "contact": {
    "button": "Senden"
  }
}
translate.t("hello"); // output: "Hallo Welt"
translate.t("car", {count: 2}); // output: "Autos"
translate.t("car", {count: 1}); // output: "Auto"
translate.t("employee", {count: 0, context: "male"}); // output: "Kein Mitarbeiter"
translate.t("employee", {count: 1, context: "male"}); // output: "Der Mitarbeiter"
translate.t("employee", {count: 2, context: "male"}); // output: "Die Mitarbeiter"
translate.t("employee", {count: 0, context: "female"}); // output: "Keine Mitarbeiterinnen"
translate.t("employee", {count: 1, context: "female"}); // output: "Die Mitarbeiterin"
translate.t("employee", {count: 2, context: "female"}); // output: "Die Mitarbeiterinnen"
translate.t("dashboard.button"}); // output: "Ok"
translate.t("contact.button"}); // output: "Senden"

Intl.PluralRules is used under the hood to get the rule for the current set locale.

For example this is in german and english:

  • -1 is one
  • 1 is one
  • everything else is other

...and in arabic:

  • less than -10 is many
  • -3 to -10 is few
  • -2 is two
  • -1 is one
  • 0 is zero
  • 1 is one
  • 2 is two
  • 3 to 10 is few
  • greater than 10 is many
Setting the Language and Listening

Setting the language:

translate.locale("de");                          // sets only the language and is guessing the region which will result in DE in this case
translate.locale("de-DE");                       // sets language and region
translate.locale(new Intl.Locale("de-DE"));      // sets language and region too
translate.locale("zh-Hant-HK");                  // sets language, script and region
translate.locale(new Intl.Locale("zh-Hant-HK")); // sets language, script and region too

Getting the language:

translate.short();   // short locale (language) like "en" or like "zh-Hant" if script was set
translate.long();    // long locale like "en-GB" or like "zh-Hant-HK" if script was set
translate.script();  // long script like "Hant" if script was set else it returns undefined
translate.region();  // region of the current locale like "DE" if "de" or "de-DE" was set

Listening to language change and unsubscribe:

// subscribe
const unsubscribe = translate.listen(() => alert("language was changed"));

// and this will unsubscribe the listener
unsubscribe();

Note: The callback will get triggered on some other changes too, like new translation resources or plugins got added.

Inspiration

This library is made with inspiration of the well known i18next framework.

License

MIT

Copyright © 2019 - 2020 Hauke Broer