Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/danburzo/nano-i18n
Tiny (experimental) i18n for JavaScript
https://github.com/danburzo/nano-i18n
i18n tagged-template-literals template-literals
Last synced: 23 days ago
JSON representation
Tiny (experimental) i18n for JavaScript
- Host: GitHub
- URL: https://github.com/danburzo/nano-i18n
- Owner: danburzo
- License: mit
- Created: 2018-09-26T07:41:13.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2021-09-07T16:33:12.000Z (about 3 years ago)
- Last Synced: 2024-10-03T18:22:40.435Z (about 1 month ago)
- Topics: i18n, tagged-template-literals, template-literals
- Language: JavaScript
- Homepage:
- Size: 101 KB
- Stars: 8
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# nano-i18n
`nano-i18n` is a tiny experimental internationalization library for JavaScript, using [tagged template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals).
## Introduction
> 🔎 **Internationalization** (often abbreviated as **i18n**) is making sure a program can be adapted for several languages / cultures. It involves translating the words, but also using date, time, and number formats to which the people from a certain culture are accustomed.
`nano-i18n` aims to offer a pleasant way of making your JavaScript app amenable to localization, without getting in the way too much. It focuses, for now, on translating strings.
## Installation
`nano-i18n` is packaged into ES & CJS format, so it works in Node as well as browsers. You can also [try out the API on RunKit](https://npm.runkit.com/nano-i18n) without installing the library.
### From the `npm` registry
Install the library using `npm` or `yarn`:
```bash
# using npm
npm install nano-i18n# using yarn
yarn add nano-i18n
```### As a `` tag
You can load the library directly in the browser as a `<script>` tag, using **unpkg**. This will get you the latest version in the UMD module format:
```html
<script src="https://unpkg.com/nano-i18n">
```## Basic usage
To use `nano-i18n`, you first need to load some translations into the store. We use the `k` (from _key_) and `v` (from _value_) tags to mark up our translations:
```js
import { load, k, v } from 'nano-i18n';// Load a key/value pair into the store
load(k`Hello, ${'World'}!`, v`Salut, ${0}!`);
```Afterwards, translate strings with the `t` tag:
```js
import { t } from 'nano-i18n';console.log(t`Hello, ${'Dan'}!`);
// => "Salut, Dan!"
```## API reference
### Literal tags
📖 **k**
Obtains the _key_ for a certain literal. By default, keys are obtained by replacing all interpolated values with the `{}` character sequence:
```js
import { k } from 'nano-i18n';k`Hello, ${'World'}`;
// => "Hello, {}"
```That means the strings you wish to translate must not otherwise contain the `{}` sequence. You may change the placeholder with the `config` method:
```js
import { config } from 'nano-i18n';config({
placeholder: '@@'
});
```📖 **v**
Generates a translation function for a literal:
```js
import { v } from 'nano-i18n';v`Salut, ${0}!`;
// => function(strings, values) {}
```When providing a translation, the interpolated values need to be numbers (i.e. `${0}`, `${1}`, et cetera). They don't necessarily need to be in sequential order. You can swap them around if the translation needs it:
```js
import { k, v, t, load } from 'nano-i18n';load(k`My name is ${0}, yours is ${1}`, v`Your name is ${1}, mine is ${0}`);
t`My name is ${'Dan'}, yours is ${'Alex'}`;
// "Your name is Alex, mine is Dan"
```📖 **t**
Get a translated string:
```js
import { t } from 'nano-i18n';t`Hello, ${'Dan'}!`;
// => "Salut, Dan!"
```If there's no translation available, it returns the normal interpolated string instead. The `log` config option controls how the library reports missing translations.
### Managing the store
📖 **load**(key: _string_, value: _string_ | _function_)
The _load_ method adds translations to the store.
You can add the translations one by one:
```js
import { load, k, v } from 'nano-i18n';load(k`Hello, ${'World'}!`, v`Salut, ${0}!`);
```Or a whole batch of translations:
```js
import { load, k, v } from 'nano-i18n';let translations = {};
translations[k`Hello, ${'World'}!`] = v`Salut, ${0}!`;
translations[k`My name is ${'name'}`] = v`Numele meu este ${0}`;load(translations);
```Or using the [computed property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) syntax:
```js
import { load, k, v } from 'nano-i18n';load({
[k`Hello, ${'World'}!`]: v`Salut, ${0}!`,
[k`My name is ${'name'}`]: v`Numele meu este ${0}`
});
```Or skipping the `k` literal tag altogether and using a string key directly:
```js
import { load } from 'nano-i18n';load('Hello, {}!', v`Salut, ${0}!`);
```You can also skip the `v` literal tag and send a simple string translation:
```js
import { load } from 'nano-i18n';load('Hello, World!', 'Salut, lume!');
```📖 **clear**()
The `clear` method removes all the translations from the store.
```js
import { clear } from 'nano-i18n';clear();
```📖 **config**(options: _object_)
Configures the library. Available options:
_log_: _number_ | _function_, default `0`
The log level for the library. Possible values:
- `0` disables logging
- `1` logs a warning in the console on a missing translation
- `2` throws an error when encountering a missing translationYou can also set up a custom logging function, in case you want to keep track of exceptions some other way:
```js
import { config } from 'nano-i18n';config({
log: function (message, key) {
/*
You could do something with `message`,
e.g. send the error to Sentry.`key` contains just the key the message
refers to.
*/
}
});
```_placeholder_: _string_, default `{}`
The string to use as placeholder for interpolated values when generating the key for a translation.
## Usage with templating languages
You may be working with a templating language, such as Mustache or its variants, that does not support tagged template literals in its syntax. The good news is that tags in general, and the `t` tag in particular, can also be used as a plain function:
```js
import { t } from 'nano-i18n';
t('Hello, World!');
// => 'Salut, lume!'
```To use string interpolation with the `t()` function:
1. For the key, use a plain string with placeholders
2. Pass the values as extra arguments to the function```js
t('My name is {}, yours is {}', 'Dan', 'Alex');
```Look in your templating language's API reference for the specifics of passing, and using, functions in templates.
## Usage with Webpack
This library can be used with Webpack to load translations from external files with the `nano-i18n/loader` loader. `nano-i18n` comes with the loader, so you don't have to install any other packages.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.json$/,
include: /locales/,
loader: 'nano-i18n/loader'
}
]
}
};
```By default, external files are expected to be JSONs containing an **array of `key`/`val` pairs**, i.e.:
**locales/ro-RO.json**
```js
[
{ key: "Hello, ${'World'}", val: 'Salut, ${0}' },
{ key: 'Some String', val: 'Un Șir Oarecare' }
// etc.
];
```With this setup in place, we can load the JSON as ready-to-use translations:
```js
import { load } from 'nano-i18n';
load(require('path/to/locales/ro-RO.json'));
````nano-i18n/loader` also accepts a `parse` option with you can use to keep the external translation files in any format, as long as you format it to `key`/`val` pairs.
Let's say you want to keep the translations in a CSV file so that it's easy to edit them in Microsoft Excel or macOS Numbers:
**locales/ro-RO.csv**
```csv
"key","val"
"Hello, ${'World'}","Salut, ${0}"
"Some String","Un Șir Oarecare"
```In our Webpack configuration, we'll parse the CSV file using the [`d3-dsv`](https://github.com/d3/d3-dsv) package:
**webpack.config.js**
```js
let { csvParse } = require('d3-dsv');module.exports = {
module: {
rules: [
{
test: /\.csv$/,
include: /locales/,
loader: 'nano-i18n/loader',
options: {
parse: text => csvParse(text)
}
}
]
}
};
```> 💡 The `parse` option accepts a function which receives as its only argument the original text to parse, and which must return an array of `key`/`val` pairs.
## See also
### Further reading
- [i18n with tagged template literals in ECMAScript 2015](https://jaysoo.ca/2014/03/20/i18n-with-es2015-template-literals/) by Jack Hsu
- [Easy i18n in 10 lines of JavaScript (PoC)](https://codeburst.io/easy-i18n-in-10-lines-of-javascript-poc-eb9e5444d71e) by Andrea Giammarchi### Other projects
- [i18n Tagged Template Literals](http://i18n-tag.kolmer.net/) by Steffen Kolmer
- [ttag](https://github.com/ttag-org/ttag)