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 🙏

© 2026 – Pkg Stats / Ryan Hefner

handlebars-i18n

v1.10.4

Published

handlebars-i18n adds internationalization to handlebars.js using i18next and Intl.

Downloads

66,988

Readme

handlebars-i18n

What it is about: handlebars-i18n adds the translation features of i18next to handlebars.js. It also provides date, number, and currency formatting via Intl. Use as node module or in the web browser. handlebars-i18n is listed amongst i18next’s official framework helpers.

License: MIT Node.js version Build Coverage Status Code Climate Known Vulnerabilities npm npm GitHub stars

Key Features & Advantages

  • handlebars-i18n comes lightweight, well tested, and with detailed examples
  • allows granular custom presets per language
  • supports Typescript
  • has an optional CLI for automatic Translations via DeepL

Please Support

handlebars-i18n is free but not free of value. If you make serious use of handlebars-i18n, I’d be delighted if you

BuyMeACoffee

Install

npm i handlebars-i18n

Import

Import with ES6 syntax:

import HandlebarsI18n from "handlebars-i18n";
HandlebarsI18n.init();

As commonJS within node environment:

const HandlebarsI18n = require("handlebars-i18n");
HandlebarsI18n.init();

Usage in web browser (old school):

<script src="handlebars.js"></script>
<script src="i18next.js"></script>
<script src="handlebars-i18n.js"></script>

<script>
  HandlebarsI18n.init()
</script>

Via CDN:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/handlebars-i18n.min.js"></script>

What Was Design

Quick Example

Initialize i18next with your language strings and default settings:

const i18next = require("i18next");

i18next.init({
  resources: {
    "en": {
      translation: {
        "phrase1": "What is good?",
        "phrase2": "{{thing}} is good."
      }
    },
    "de": {
      translation: {
        "phrase1": "Was ist gut?",
        "phrase2": "{{thing}} ist gut."
      }
    }
  },
  lng: "en",
  compatibilityJSON: 'v2'
});

Set your Handlebars.js data object:

let data = {
  myItem: "handlebars-i18n",
  myPrice: 1200.99,
  myDate: "2020-03-11T03:24:00"
}

Initialize handlebars-i18n:

HandlebarsI18n.init();

Optionally configure your language specific number, currency, and date-time defaults:

HandlebarsI18n.configure([
  ["en", "PriceFormat", {currency: "USD"}],
  ["de", "PriceFormat", {currency: "EUR"}]
]);

Finally use in template:

<p> {{__ "phrase1"}} </p>
  • output: en → What is good? | de → Was ist gut?
<p> {{__ "phrase2" thing=myItem}} </p>
  • output: en → handlebars-i18n is good. | de → handlebars-i18n ist gut.
<p> {{_date myDate}} </p>
  • output: en → March 11, 2020 at 3:24 AM | de → 11.3.2020, 03:24
<p> {{_price myPrice}} </p>
  • output: en → $1,200.99 | de → 1.200,99 $

Detailed Examples

:point_right: See the examples folder in the repo for more use cases and details.

  • Open examples/browser-example/index.html in your web browser to see an implementation with a simple UI.
  • Prompt npm run example:js from the root of this repo to log a very basic node example to console.
  • Prompt npm run example:ts to compile and log a typescript example.

Additional CLI Helper for Handlebars-i18n available

:metal: handlebars-i18n has its own command line interface handlebars-i18n-cli.

npm i handlebars-i18n-cli --save-dev
  • programmatically extract/ update translation strings from handlebars templates and generate i18next conform JSON files from it
  • automatic translation of i18next JSON via DeepL’s free API

Template Functions

__

Returns the phrase associated with the given key for the selected language. __ will take all options i18next’s t-function would take. The key can be passed hard encoded in the template when written in quotes:

{{__ "keyToTranslationPhrase"}}

… or it can be referenced via a handlebars variable:

{{__ keyFromHandlebarsData}}

Variable Replacement

Template usage:

{{__ "whatIsWhat" a="Everything" b="fine"}}

The i18next resource:

"en" : {
  translation : {
    "whatIsWhat" : "{{a}} is {{b}}."
  }
}
  • output: en → Everything is fine.

Plurals

{{__ "keyWithCount" count=8}}
"en" : {
  translation : {
    "keyWithCount" : "{{count}} item", 
    "keyWithCount_plural" : "{{count}} items"
  }
}, ...

Override the globally selected language

{{__ "key1" lng="de"}}

Will output the contents for de even though a different language is globally set.

Looping over an array (or object) of translations

<ul>
  {{#each (__ "fruits")}}
    <li>{{this}}</li>
  {{/each}}
</ul>

In this case the key fruits would contain an array of translation strings, like:

{
  en: {
    translation: {
      fruits: ["Apple", "Banana", "Cherry"]
    }
  },
  returnObjects: true
}

It is recommended to set returnObjects actively to true in the i18next.init object if you want to loop over an array or objects of properties.


keyExists

Checks if a i18next translation key exists. Returns true or false.

{{#if (keyExists "myKey")}} {{__ "myKey"}} {{/if}}

_locale

Returns the shortcode of i18next’s currently selected language such as en, de, ja … etc.

{{_locale}}

localeIs

Checks a string against i18next’s currently selected language. Returns true or false.

{{#if (localeIs "en")}} ... {{/if}}

_date

Outputs a formatted date according to the language specific conventions.

{{_date}}

If called without argument the current date is returned. Any other input date can be passed as a conventional date string, a number (timestamp in milliseconds), or a date array. _date accepts all arguments Javascript’s new Date() constructor would accept.

Date argument given as date string:

{{_date "2020-03-11T03:24:00"}}

or

{{_date "December 17, 1995 03:24:00"}}

Date argument given as number (milliseconds since begin of unix epoch):

{{_date 1583922952743}}

Date argument given as javascript date array [year, monthIndex [, day [, hour [, minutes [, seconds [, milliseconds]]]]]]:

{{_date "[2012, 11, 20, 3, 0, 0]"}}

Additional arguments for formatting:

You can add multiple arguments for individual formatting. See Intl DateTimeFormat for your option arguments. Alternatively check this repo’s TS types in handlebars-i18n.d.ts.

{{_date 1583922952743 year="2-digit" day="2-digit" timeZone="America/Los_Angeles"}}

_dateAdd

Adds a time offset in a given unit to a date, returns the modified date.

{{_dateAdd "1996-12-17" 24 unit="hour"}}
  • output: en → 12/18/1996

The first argument is a date (see function _date for valid date inputs). The second argument is a time amount given as number. The option unit specifies the time amount. Possible units are second | minute | hour | day | week | month | quarter | year (default is hour). Further options as for function _date can be applied.


_dateDiff

Outputs the time difference between two given dates in the requested unit.

{{_dateDiff "2000-12-17" "2001-12-17" unit="year"}}
  • output: en → in 1 year

The second date argument is subtracted from the first. If the difference is a positive value, a future event statement is made. A negative value refers to a past date. (If no second argument is given, the default date is the present moment). Allowed date input formats are similar to _date, options equal _dateRel. Default unit is hour.


_dateRel

Outputs a string with a relative date statement, formatted according to the language specific conventions.

{{_dateRel 7 unit="hour"}}
  • output: en → in 7 hours
{{_dateRel -7 unit="hour"}}
  • output: en → 7 hours ago

A positive number argument leads to a future event statement, a negative refers to a past date. Possible units are second | minute | hour | day | week | month | quarter | year (default is hour). For a complete set of options (such as numberingSystem or localeMatcher) see Intl.RelativeTimeFormat Constructor. Alternatively check this repo’s TS types in handlebars-i18n.d.ts.


_num

Outputs a formatted number according to the language specific conventions of number representation.

{{_num 3.14159}}

Additional arguments for formatting:

You can add multiple arguments for individual formatting. See Intl NumberFormat for your option arguments. Alternatively check this repo’s TS types in handlebars-i18n.d.ts.

{{_num 3.14159 maximumFractionDigits=2}}
  • output: en → 3.14 | de → 3,14

_price

Outputs a formatted currency string according to the language specific conventions of price representation.

{{_price 9999.99}}

Additional arguments for formatting:

You can add multiple arguments for individual currency formatting. See Intl NumberFormat for your option arguments. Alternatively check this repo’s TS types in handlebars-i18n.d.ts.

{{_price 1000 currency="JPY" minimumFractionDigits=2}}

How to use HandlebarsI18n.configure method

Generic language format settings

Instead of defining the formatting options for each date, number or price anew, you can configure global settings for all languages or only for specific languages.

HandlebarsI18n.configure("all", "DateTimeFormat", {timeZone: "America/Los_Angeles"});

First argument is the language shortcode or "all" for all languages. Second is the format option you want to address (DateTimeFormat, RelativeTimeFormat, NumberFormat, or PriceFormat). Third argument is the options object with the specific settings.

Examples for generic settings:

HandlebarsI18n.configure("all", "RelativeTimeFormat", {style: "long", unit: "second"});
HandlebarsI18n.configure("all", "NumberFormat", {numberingSystem: "latn", maximumFractionDigits: 0});
HandlebarsI18n.configure("all", "PriceFormat", {currency: "HKD", currencyDisplay: "code"});

Custom language format subsets

You can also define specific subsets to be used in the template, i.e. if you want the date in different formats such as:

  • 2020 (year-only)
  • 11.3.2020 (standard-date)
  • 7:24:02 (time-only)

To do this, define a 4th parameter with a custom name:

HandlebarsI18n.configure([
  ["en", "DateTimeFormat", {year: "numeric"}, "year-only"],
  ["en", "DateTimeFormat", {year: "numeric", month: "numeric", day: "numeric"}, "standard-date"],
  ['en', 'DateTimeFormat', {hour: "numeric", minute: "numeric", second: "numeric", hour12: false}, "time-only"]
]);

Call a subset in template with the parameter format="custom-name", like:

{{_date myDate format="year-only"}}

Subsets must be defined per language, a subset for "all" is invalid.

The lookup cascade

The general lookup cascade is:

  • 1st Priority: The argument given in the template for custom configurations by the key "format", i.e. {{_date format="my-custom-format"}}
  • 2nd Priority: The extra argument(s) given in the template, e.g. {{_date timeZone="America/Los_Angeles" year="2-digit"}}
  • 3rd Priority: The global setting configured for the current language, such as "en"
  • 4th Priority: The global setting configured for all languages
  • Default: The Intl default setting

Example:

This defines that all prices for all languages are represented in Dollar:

HandlebarsI18n.configure("all", "PriceFormat", {currency: "USD"});

This defines that all prices for all languages are represented in Dollar, but that for the language French the currency is Euro:

HandlebarsI18n.configure([
  ["all", "PriceFormat", {currency: "USD"}],
  ["fr", "PriceFormat", {currency: "EUR"}]
]);

Reset existing configuration

Dismiss all existing configurations:

HandlebarsI18n.reset();

Using custom instances of Handlebars and/or i18next

Sometimes you may want to use a Handlebars object you have already modified before, or you may want to use multiple discrete instances of Handlebars. In this case you can pass you custom Handlebars instance to the init function to use it instead of the generic Handlebars object like so:

const HandlebarsModified = require("handlebars");
HandlebarsModified.registerHelper("foo", function () {
  return "bar"
});
HandlebarsI18n.init(HandlebarsModified);

HandlebarsI18n will have your previously defined method foo by now.

The same can be done for a custom instance of i18next. Pass it as the second argument to the init function.

const i18nextCustom = require("i18next");
i18nextCustom.createInstance( /* pass some params here ... */);
HandlebarsI18n.init(null, i18nextCustom);

Run tests

npm test

License

MIT License, Copyright (c) 2020–26 Florian Walzel

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

Merci à vous

For your contribution, I would like to thank @MickL, @dargmuesli, and @DiefBell.

Note on alternatives

There is a different package named handlebars-i18next by @jgonggrijp which might also suit your needs. Cheers!