Skip to the content.

Internationalization (i18n)

Lips includes built-in support for internationalization, making it easy to create multilingual applications including many other util formats like Date, Metri Units, Float & Currency Number, etc by languages and countries.

Setting up Languages

Initialize Lips with a default language and set up dictionaries for each supported language:

// Create dictionaries for each language
const englishDictionary = {
  'Welcome': 'Welcome',
  'Hello, {name}': 'Hello, {name}',
  'items_count': '{count} items',
  'submit_button': 'Submit'
};

const frenchDictionary = {
  'Welcome': 'Bienvenue',
  'Hello, {name}': 'Bonjour, {name}',
  'items_count': '{count} éléments',
  'submit_button': 'Soumettre'
};

const spanishDictionary = {
  'Welcome': 'Bienvenido',
  'Hello, {name}': 'Hola, {name}',
  'items_count': '{count} elementos',
  'submit_button': 'Enviar'
};

// Initialize Lips with i18n support
const lips = new Lips({ debug: true });

// Set dictionaries
lips.i18n.setDictionary('en', englishDictionary);
lips.i18n.setDictionary('fr', frenchDictionary);
lips.i18n.setDictionary('es', spanishDictionary);

Changing Languages

You can change the current language at any time:

// Switch to French
lips.language('fr');

// Switch to Spanish
lips.language('es-ES');

// Switch back to English
lips.language('en');

When the language changes, all components that display translated content with i18n attribute flag will automatically update.

Using Translations

Translations are automatically applied to text content in your templates:

<h1 i18n>Welcome</h1>
<p i18n>Hello, {state.name}</p>
<span i18n>{state.items.length} items</span>
<button i18n>Submit</button>

If the current language is French, this would render as:

<h1>Bienvenue</h1>
<p>Bonjour, John</p>
<span>5 éléments</span>
<button>Soumettre</button>

Language Variants

You can define variants for regional differences:

const englishDictionary = {
  'color': {
    '*': 'color',      // Default (US English)
    'GB': 'colour',    // British English
    'CA': 'colour'     // Canadian English
  }
};

// Set the dictionary
lips.i18n.setDictionary('en', englishDictionary);

// Switch to British English
lips.language('en-GB');

Translation with Variables

You can include variables in translation strings using @format attribute:

// Dictionary entry
{
  'items_count': {
    'type': 'variable',
    'value': '{count} items'
  },
  'welcome_user': {
    'type': 'variable',
    'value': 'Welcome back, {name}!'
  }
}

// Template usage
<p @format="items_count, { count: state.items.length }"/>
<p @format="welcome_user, { name: state.user.name }"/>

Handling Plurals format

You can define different translations based on numeric count value:

// Dictionary entry with plural forms
{
  'items_count': {
    'type': 'plural',
    'value': {
      '*': '{count} items',    // Default (plurals)
      '1': '{count} item',     // Exactly 1
      '0': 'No items'          // Zero
    }
  }
}

// Template usage
<p @format="items_count, { count: state.items.length }"/>

Handling Condition format

You can set up different translations based on conditions value:

// Dictionary entry with plural forms
{
  'allowed_age_check': {
    'type': 'condition',
    'value': {
      'age >= 18': 'Let do this!',
      'age < 18': '{age} years old users are not allowed'
    }
  }
}

// Template usage
<p @format="allowed_age_check, { age: input.user.age }"/>

Excluding Content from Translation

Sometimes you may want to exclude specific content from translation:

<div no-translate>This text will not be translated</div>

<div>
  <span no-translate>Untranslated</span>
  <span>Translated</span>
</div>

Manual Translation

You can also use the translation API directly:

const component = {
  handler: {
    getTranslation(text){
      const { text } = this.lips.i18n.translate( text )
      return text
    },
    getLocalizedMessage(key, params) {
      return this.lips.i18n.format( key, params );
    }
  },
  
  default: `
    <div>
      <p>{self.getLocalizedMessage('welcome_user', { name: state.user.name })}</p>
      <button>{self.getTranslation('Submit')}</button>
    </div>
  `
};

The built-in i18n support makes it easy to create multilingual applications with Lips, without requiring external libraries or complex setup.