{"id":28384483,"url":"https://github.com/formatjs/dust-intl","last_synced_at":"2026-03-11T03:03:11.403Z","repository":{"id":13658890,"uuid":"16352480","full_name":"formatjs/dust-intl","owner":"formatjs","description":"Dust helpers for internationalization.","archived":false,"fork":false,"pushed_at":"2016-01-29T16:35:14.000Z","size":706,"stargazers_count":49,"open_issues_count":8,"forks_count":11,"subscribers_count":23,"default_branch":"master","last_synced_at":"2026-02-28T21:08:15.625Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://formatjs.io/dust/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/formatjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-29T17:31:45.000Z","updated_at":"2025-04-17T01:52:40.000Z","dependencies_parsed_at":"2022-08-28T21:40:27.385Z","dependency_job_id":null,"html_url":"https://github.com/formatjs/dust-intl","commit_stats":null,"previous_names":["yahoo/dust-helper-intl","yahoo/dust-intl"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/formatjs/dust-intl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formatjs%2Fdust-intl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formatjs%2Fdust-intl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formatjs%2Fdust-intl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formatjs%2Fdust-intl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/formatjs","download_url":"https://codeload.github.com/formatjs/dust-intl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formatjs%2Fdust-intl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30368595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-30T08:38:49.078Z","updated_at":"2026-03-11T03:03:11.386Z","avatar_url":"https://github.com/formatjs.png","language":"JavaScript","readme":"Dust Intl\n=========\n\nDust helpers for internationalization.\n\n[![npm Version][npm-badge]][npm]\n[![Build Status][travis-badge]][travis]\n[![Dependency Status][david-badge]][david]\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/dust-intl.svg)](https://saucelabs.com/u/dust-intl)\n\n**This package used to be named `dust-helper-intl`.**\n\n\nOverview\n--------\n\n\n### Goals\n\n* Integrate internationalization features with [Dust][] to lower the barrier for localizing Dust templates.\n\n* Build on current and emerging JavaScript [`Intl`][Intl] standards — architect in a future-focused way. Leverage industry standards used in other programming langages like [CLDR][] locale data, and [ICU Message syntax][ICU].\n\n* Run in both Node.js and in the browser.\n\n\n### How It Works\n\n**Template Source:**\n\n```dust\n\u003cb\u003ePrice:\u003c/b\u003e {@formatNumber val=price style=\"currency\" currency=\"USD\"/}\n```\n\n**Render Template:**\n\n```js\nvar context = {\n    intl: {\n        locales: 'en-US'\n    },\n    price: 1000\n};\n\ndust.renderSource(template, context, function(err, html) {\n    console.log(html);\n});\n```\n\n**Output:**\n\n```html\n\u003cb\u003ePrice:\u003c/b\u003e $1,000.00\n```\n\n\n### Features\n\n* Formats **numbers** and **dates/times**, including those in complex messages using the JavaScript built-ins: [`Intl.NumberFormat`][Intl-NF] and [`Intl.DateTimeFormat`][Intl-DTF], respectively.\n\n* Formats **relative times** (e.g., \"3 hours ago\") using the [Intl RelativeFormat][Intl-RF] library which uses [CLDR][] locale data.\n\n* Formats complex messages, including **plural** and **select** arguments using the [Intl MessageFormat][Intl-MF] library which uses [CLDR][] locale data and works with [ICU Message syntax][ICU].\n\n\nUsage\n-----\n\n\n### `Intl` Dependency\n\nThis package assumes that the [`Intl`][Intl] global object exists in the runtime.\n`Intl` is present in all modern browsers _except_ Safari, and there's work happening to [integrate `Intl` into Node.js][Intl-Node].\n\n**Luckly, there's the [Intl.js][] polyfill!** You will need to conditionally load the polyfill if you want to support runtimes which `Intl` is not already built-in.\n\n\n#### Loading Intl.js Polyfill in a browser\n\nIf the browser does not already have the `Intl` APIs built-in, the Intl.js Polyfill will need to be loaded on the page along with the locale data for any locales that need to be supported:\n\n```html\n\u003cscript src=\"intl/Intl.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"intl/locale-data/jsonp/en-US.js\"\u003e\u003c/script\u003e\n```\n\n_Note: Modern browsers already have the `Intl` APIs built-in, so you can load the Intl.js Polyfill conditionally, by for checking for `window.Intl`._\n\n#### Loading Intl.js Polyfill in Node.js\n\nConditionally require the Intl.js Polyfill if it doesn't already exist in the runtime. As of Node \u003c= 0.10, this polyfill will be required.\n\n```js\nif (!global.Intl) {\n    require('intl');\n}\n```\n\n_Note: When using the Intl.js Polyfill in Node.js, it will automatically load the locale data for all supported locales._\n\n\n### Registering Helpers in a Browser\n\nFirst, load Dust and this package onto the page:\n\n```html\n\u003cscript src=\"dustjs/dust-core.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"dust-intl/dust-intl.min.js\"\u003e\u003c/script\u003e\n```\n\nBy default, Handlebars Intl ships with the locale data for English built-in to the runtime library. When you need to format data in another locale, include its data; e.g., for French:\n\n```html\n\u003cscript src=\"dust-intl/locale-data/fr.js\"\u003e\u003c/script\u003e\n```\n\n_Note: All 150+ locales supported by this package use their root BCP 47 langage tag; i.e., the part before the first hyphen (if any)._\n\nThen, register the helpers with Dust:\n\n```js\nDustIntl.registerWith(Dust);\n```\n\nThis package will create the `DustIntl` global that has the `registerWith()` function.\n\n\n### Registering Helpers in Node.js\n\nImport Dust and this package, then register the Intl helpers with Dust:\n\n```js\nvar Dust     = require('dustjs-linkedin'),\n    DustIntl = require('dust-helper-intl');\n\nDustIntl.registerWith(Dust);\n```\n\n_Note: in Node.js, the data for all 150+ locales is pre-loaded and does not need to be loaded manually._\n\n\n### Supplying i18n Data to Dust\n\nDust has just the **context** in which to pass all information.\nThis package looks in the `intl` key in the context for the i18n used by the helpers.\n\n\n#### `context.intl.locales`\n\nA string with a BCP 47 language tag, or an array of such strings; e.g., `\"en-US\"`.\nIf you do not provide a locale, the default locale will be used, but you should _always_ provide one!\n\nThis value is used by the helpers when constructing the underlying formatters.\n\n\n#### `context.intl.messages`\n\nThis is an object the keys of which identify messages and the values are the messages themselves.\nThese messages are referenced by the `_key` parameter of the `{@intlMessage}` helper.\nOne common use is to put complex message strings here.\nThe strings should be appropriate for the locale specified by `context.intl.locales`.\n\n**Note:** These messages _need_ to follow the [ICU Message][ICU] standard.\nLuckily this is a common standard that professional translators should already be familiar with.\n\n```js\n// Static collection of messages, per-locale.\nvar MESSAGES = {\n    whoHosted: '{hostName} hosted the party!',\n    petUpsell: 'Pets? We have: {numPets, number, integer}',\n    ...\n}\n```\n\nThese statically defined message strings can be provided to dust via `context.intl.messages`:\n\n```js\n// Supply the intl data as part of the context.\nvar context = {\n    intl: {\n        locales: 'en-US',\n        messages: MESSAGES\n    },\n    ...\n};\n\ndust.renderSource(template, context, function(err, html) {\n    console.log(html);\n});\n```\n\n\n#### `context.intl.formats`\n\nObject with user defined options for format styles.\nThis is used to supply custom format styles and is useful you need supply a set of options to the underlying formatter; e.g., outputting a number in USD:\n\n```js\n{\n    number: {\n        USD: {\n            style   : 'currency',\n            currency: 'USD'\n        }\n    },\n\n    date    : {...},\n    time    : {...},\n    relative: {...}\n}\n```\n\nThese pre-defined formats map to their respective helpers of the same type, and all `context.intl.formats` are used by the `{@formatNumber}`, `{@formatDate}`, and `{@formatTime}` helpers.\nThey can then be used by String name/path like this:\n\n```dust\n{@formatNumber val=100 formatName=\"USD\"/}\n```\n\n\n### Helpers\n\n\n#### `{@intl}`\n\nBlock helper used to create a new `intl` data scope by updating the [i18n data supplied to Dust](#supplying-i18n-data-to-dust) within the block.\nThis is useful when you need to render part of the page in a particular locale, or need to supply the i18n data to Dust via the template context.\n\nThe following example uses `{@intl}` to set the locale to French and will output `\"1 000\"`:\n\n```dust\n{@intl locales=\"fr-FR\"}\n    {@formatNumber val=1000/}\n{/intl}\n```\n\n\n#### `{@formatDate}`\n\nFormats dates using [`Intl.DateTimeFormat`][Intl-DTF], and returns the formatted string value.\n\n```dust\n{@formatDate val=now weekday=\"long\" timeZone=\"UTC\"/}\n```\n\n```js\nvar context = {\n    intl: {\n        locales: 'en-US'\n    },\n    now: Date.now()\n};\n\nDust.renderSource(template, context, function(err, html) {\n    console.log(html); // =\u003e \"Tuesday, August 12, 2014\"\n});\n```\n\n**Parameters:**\n\n* `val`: `Date` instance or `String` timestamp to format.\n\n* `[format]`: Optional String path to a predefined format on [`context.intl.formats`](#contextintlformats). The format's values are merged with other parameters.\n\nOther parameters passed to this helper become the `options` argument when the [`Intl.DateTimeFormat`][Intl-DTF] instance is created.\n\n\n#### `{@formatTime}`\n\nThis delegates to the `{@formatDate}` helper, but first it will reference any `formatName` from [`context.intl.formats.time`](#contextintlformats).\n\n\n#### `{@formatRelative}`\n\nFormats dates relative to \"now\" using [`IntlRelativeFormat`][Intl-RF], and returns the formatted string value.\n\n```dust\n\u003cp\u003ePosted {@formatRelative val=postDate/}\u003c/p\u003e\n```\n\n```js\nvar context = {\n    intl: {\n        locales: 'en-US'\n    },\n    postDate: Date.now() - (1000 * 60 * 60 * 24)  // 1 day ago.\n};\n\nDust.renderSource(template, context, function(err, html) {\n    console.log(html); // =\u003e \"\u003cp\u003ePosted yesterday\u003c/p\u003e\"\n});\n```\n\n**Parameters:**\n\n* `val`: `Date` instance or `String` timestamp to format.\n\n* `[format]`: Optional String path to a predefined format on [`context.intl.formats`](#contextintlformats). The format's values are merged with other parameters.\n\nOther parameters passed to this helper become the `options` argument when the [`Intl.DateTimeFormat`][Intl-DTF] instance is created.\n\n\n#### `{@formatNumber}`\n\nFormats numbers using [`Intl.NumberFormat`][Intl-NF] and returns the formatted string value.\n\n```dust\n{@formatNumber val=price style=\"currency\" currency=\"USD\"/}\n```\n\n```js\nvar context = {\n    intl: {\n        locales: 'en-US'\n    },\n    price = 100\n};\n\nDust.renderSource(template, context, function(err, html) {\n    console.log(html); // =\u003e \"$100.00\"\n});\n```\n\n**Parameters:**\n\n* `val`: `Number` to format.\n\n* `[format]`: Optional String path to a predefined format on [`context.intl.formats`](#contextintlformats). The format's values are merged with other parameters.\n\nOther parameters passed to this helper become the `options` argument when the [`Intl.NumberFormat`][Intl-NF] instance is created.\n\n\n#### `{@formatMessage}`\n\nFormats [ICU Message][ICU] strings with the given values supplied as the hash arguments.\n\n```\nYou have {numPhotos, plural,\n    =0 {no photos.}\n    =1 {one photo.}\n    other {# photos.}}\n```\n\n```dust\n{@formatMessage _key=\"photos\" numPhotos=numPhotos/}\n```\n\n```js\nvar context = {\n    intl: {\n        locales: 'en-US',\n        messages: {\n            photos: '...', // String from code block above.\n            ...\n        },\n        numPhotos: 1\n    }\n};\n\nDust.renderSource(template, context, function(err, html) {\n    console.log(html); // =\u003e \"You have one photo.\"\n});\n```\n\n**Parameters:**\n\nThe parameters represent the name/value pairs that are used to format the message by providing values for its argument placeholders.\nA few parameters have special meaning and are used by this helper.\n\n* `_msg`: `String` message or [`IntlMessageFormat`][Intl-MF] instance to format with the given parameters as the values.\n\n* `_key`: `String` to lookup the message in [`context.intl.messages`](#contextintlmessages).\n\n**Note:** It is recommended to use `_key` instead of including the literal message string in the template.\n\n\n\nLicense\n-------\n\nThis software is free to use under the Yahoo! Inc. BSD license.\nSee the [LICENSE file][LICENSE] for license text and copyright information.\n\n\n[npm]: https://www.npmjs.org/package/dust-intl\n[npm-badge]: https://img.shields.io/npm/v/dust-intl.svg?style=flat-square\n[travis]: https://travis-ci.org/yahoo/dust-intl\n[travis-badge]: http://img.shields.io/travis/yahoo/dust-intl.svg?style=flat-square\n[david]: https://david-dm.org/yahoo/dust-intl\n[david-badge]: https://img.shields.io/david/yahoo/dust-intl.svg?style=flat-square\n[Dust]: http://linkedin.github.io/dustjs/\n[Intl-MF]: https://github.com/yahoo/intl-messageformat\n[Intl]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl\n[Intl-NF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat\n[Intl-DTF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\n[ICU]: http://userguide.icu-project.org/formatparse/messages\n[CLDR]: http://cldr.unicode.org/\n[Intl.js]: https://github.com/andyearnshaw/Intl.js\n[Intl-Node]: https://github.com/joyent/node/issues/6371\n[LICENSE]: https://github.com/yahoo/dust-helper-intl/blob/master/LICENSE\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformatjs%2Fdust-intl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fformatjs%2Fdust-intl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformatjs%2Fdust-intl/lists"}