npm package: @soydaddy/i18n
Description: Simple and lightweight message localisation
Author: soyDaddy
Latest version: 1.2.1

# @soydaddy/i18n

Simple and lightweight message localization for JavaScript projects.

## Installation

- `pnpm add @soydaddy/i18n` or
- `yarn add @soydaddy/i18n` or
- `npm i @soydaddy/i18n`

## Usage

```js
const I18n = require('@soydaddy/i18n');
const path = require('path');

// Initialize I18n with default locale and an empty locales object
const i18n = new I18n('english', {});

// Load locales asynchronously
(async () => {
    await i18n.loadLocales(path.join(__dirname, 'locales'));
})();

// Check if the locale exists and get the locale
const messages = i18n.getLocale('spanish');
console.log(messages('example')); // -> Hola, mundo

// Get a message from a specific locale
console.log(i18n.getMessage('spanish', 'example')); // -> Hola, mundo
```

### Examples

#### Manually Loading Translations

Load translations manually by creating a locales object and passing it to the `I18n` constructor:

```js
const I18n = require('@soydaddy/i18n');

const locales = {
    english: {
        greeting: {
            hello: 'Hello, world'
        }
    },
    spanish: {
        greeting: {
            hello: 'Hola, mundo'
        }
    }
};

const i18n = new I18n('english', locales);

console.log(i18n.getMessage('spanish', 'greeting.hello')); // -> Hola, mundo
console.log(i18n.getMessage('english', 'greeting.hello')); // -> Hello, world
```

#### Loading All Translation Files

To load all translation files from a directory, use the `loadLocales` method:

```js
const I18n = require('@soydaddy/i18n');
const path = require('path');

const i18n = new I18n('english', {});

(async () => {
    await i18n.loadLocales(path.join(__dirname, 'locales'));

    console.log(i18n.getMessage('spanish', 'greeting.hello')); // -> Hola, mundo
    console.log(i18n.getMessage('english', 'greeting.hello')); // -> Hello, world
})();
```

### Directory Structure for Translations

Ensure you have the following directory structure for your translation files:

```
locales/
├── english/
│   └── greeting.yml
├── spanish/
│   └── greeting.yml
```

#### `locales/english/greeting.yml`

```yaml
greeting:
  hello: "Hello, world"
```

#### `locales/spanish/greeting.yml`

```yaml
greeting:
  hello: "Hola, mundo"
```

### Placeholders

i18n supports both positional and named placeholders.

```js
{ // a locale object
    "positional": {
        "strings": "I like %s", 
        "numbers": "%d %s %d = %d"
    },
    "named": {
        "example1": "Hi, I'm {name} and I am from {location}",
        "example2": "Hi, I'm {person.name} and I am from {person.location}"
    }
}
```

```js
messages('positional.strings', 'chocolate'); // I like chocolate

messages('positional.numbers', 5, '+', 5, 10); // 5 + 5 = 10

messages('named.example1', {
    name: 'Someone',
    location: 'Somewhere'
}); // Hi, I'm Someone and I am from Somewhere

messages('named.example2', {
    person: {
        name: 'Someone',
        location: 'Somewhere'
    }
}); // Hi, I'm Someone and I am from Somewhere
```

### Pluralization

i18n supports basic pluralization. If the message is an array, the first placeholder value will be "eaten" (consumed) and the correct message will be returned.

```js
{ // a locale object
    "example1": [
        "You only have one %s",
        "You have %d %ss"
    ],
    "example2": [
        "You don't have any {item}s",
        "You only have one {item}",
        "You have {number} {item}s"
    ]
}
```

```js
messages('example1', 1, 1, 'item'); // You only have one item
messages('example2', 0, { number: 0, item: 'car' }); // You don't have any cars
```

### API

#### `new I18n(default_locale, locales, fallback_locale?)`

Create a new I18n instance.

- `default_locale` - The name of the default locale
- `locales` - An object of localized messages
- `fallback_locale` - Optional fallback locale if a translation is missing in the requested locale

#### `I18n#default_locale`

The name of the default locale.

#### `I18n#locales`

An array of the names of the locales you created.

#### `I18n#loadLocales(localesPath: string): Promise<void>`

Asynchronously loads locales from the specified path.

#### `I18n#getAllMessages(message, ...args)`

Get a message in all locales.

- `message` - Dot notation string for the message
- `...args` - Placeholders/pluralization

#### `I18n#getLocale(locale)`

Get a locale.

- `locale` - Locale name

Returns a function which calls `I18n#getMessage` using the given locale name (or the default).

#### `I18n#getMessage(locale, message, ...args)`

Get a message from a specific locale.

- `locale` - Locale name
- `message` - Dot notation string for the message
- `...args` - Placeholders/pluralization

#### `I18n#getMessages(locales, message, ...args)`

Get a message from multiple locales.

- `locales` - Array of locale names
- `message` - Dot notation string for the message
- `...args` - Placeholders/pluralization

## Support

[![Discord support server](https://discordapp.com/api/guilds/1109913004079853621/widget.png?style=banner4)](https://discord.gg/hYQWbxjMUt)

© 2023 soyDaddy