intl-fmt
v3.13.0
Published
This library provides an API to format dates, numbers, strings, and pluralization using ICU message format supporting tags.
Downloads
19
Maintainers
Readme
Intl Fmt
This library provides an API to format dates, numbers, strings, and pluralization using ICU message format supporting tags.
This is a fork of react-intl.
Read about the inspiration for this fork in the original react-intl issue discussing tags here.
It uses the same well tested code to expose an internationalization API without any React dependencies
It add supports for
Tags
in translation messages: "please <x:link>click here</x:link>"
There are 2 breaking changes:
- whitespace inside plural ICU messages is now preserved. This may impact your existing translations.
- The main browser export name has been changed from
ReactIntl
toIntlFmt
, this does not impact NodeJS usage.
You may need to set the
requireOther: false
option for backward compatibility if your ICU complex messages are missing the other option.
Using React?
Use react-intl-fmt, the API is compatible with react-intl.
Features
- Display numbers with separators.
- Display dates and times correctly.
- Display dates relative to "now".
- Pluralize labels in strings.
- Support for 150+ languages.
- Runs in the browser and Node.js.
- Built on standards.
- Extended to support
Tags
- Customize the method names used for formatting
This supports the ICU message translation format, read more about it here.
Tags are not part of the ICU message standard.
Differences from the original package include:
- As well as supporting ICU messages, this package also supports the use of
tags
in translations. Whats a tag? - No React dependency - want to use
Tags
with React? See react-intl-fmt, a drop-in replacement for react-intl
Whats a Tag?
A tag
enables style placeholders to be included in a translation message without including any of the
style information in the translation message. Named tags can be used to provide hints about context to translators.
Tags can be used in combination with all ICU message features. Heres a quick example:
import IntlFmt from 'intl-fmt';
const fmt = new IntlFmt();
const msgDescriptor = {
id: 'demo',
defaultMessage: 'Agree to our <x:link>terms and conditions</x:link>?'
};
const formattedMsg = fmt.message(msgDescriptor, {
link: text => <a href='#'>{text}</a>
});
console.log(formattedMsg); // Agree to our <a href='#'>terms and conditions</a>?
Read the original react-intl issue discussing tags here.
More information about using tags below.
Overview
Intl Fmt uses packages that are forked form FormatJS.
Intl Fmt extends the FormatJS packages to include support for tags
.
Original Documentation
The original React Intl's docs are in the GitHub repo's Wiki Documentation.
The original documentation includes all the information you need for importing locale data and the Intl
polyfill.
The API for the the format*
methods is almost identical. Method names have been shortened by removing the format
prefix from each method.
See the original documentation for more detailed API information.
Usage
You must create an instance of IntlFmt
.
import IntlFmt from 'intl-fmt';
import englishMessages from './translations/en/json';
const locale = 'en';
const fmtOpts = {
messages: englishMessages
// set other options here
};
const fmt = new IntlFmt(locale, fmtOpts);
Package Exports
default
: IntlFormatter - the main class used for formatting localized valuesFormatter
: IntlFormatter - a named instance of thedefault
export, to make browser usage easierHtmlFormatter
: IntlHtmlFormatter - A formatter with additional methods for rendering formatted text as HTML elementsaddLocaleData: function
: Used to add additional locale data into the current environmentdefineMessages: function
: A utility method for provide a hook to babel plugins to messages at build timestringBuilderFactory
: The default factory method used to formatmessage
stringsarrayBuilderFactory
: An alternative factory method that can be used to return formattedmessage
strings as arraysstringFormatFactory
: The default factory method for formatting message argument valuesbuilderContextFactory
: The default factory for creating builder context instances
Locale Data
You may need to polyfill NodeJS or polyfill the browser environment for intl-fmt to work correctly.
To use intl-fmt you'll likely need to load locale data into your Node or browser environment. I recommend reading the original documentation for configuring your environment and use that as a reference for the example below.
As you can see below, loading locale data is the same as before - you just import from intl-fmt
instead of react-intl
.
// app.js
import {addLocaleData} from 'intl-fmt';
import en from 'intl-fmt/locale-data/en';
import fr from 'intl-fmt/locale-data/fr';
import es from 'intl-fmt/locale-data/es';
addLocaleData([...en, ...fr, ...es]);
// ...
Currently, importing from a CDN is NOT supported If you want CDN, please submit an Issue/PR that publishes releases as part of the build process
// This is NOT CURRENTLY SUPPORTED
<!-- Load ReactIntl and its locale data for French. -->
<script src="https://unpkg.com/intl-fmt@latest/dist/intl-fmt.min.js"></script>
<script src="https://unpkg.com/intl-fmt@latest/locale-data/fr.js"></script>
<script>
IntlFmt.addLocaleData(IntlFmtLocaleData.fr);
</script>
Intl Formatter API
static extend(options: createFormatterOpts): IntlFmt
A factory method for generating new IntlFmt
classes that include custom shorthand method names.
Many i18n packages use either _()
or t()
for formatting translated messages. You can now use this factory method to assign your own shorthand syntax to the IntlFmt
class.
Define the createFormatterOpts:
message?: string
: The short method name formessage()
.htmlMessage?: string
: The short method name forhtmlMessage()
.date?: string
: The short method name fordate()
.time?: string
: The short method name fortime()
.number?: string
: The short method name fornumber()
.relative?: string
: The short method name forrelative()
.plural?: string
: The short method name forplural()
.
Example:
import IntlFmt from 'intl-fmt';
// Generate a new Formatter class
const CustomFormatter = IntlFmt.extend({
message: 'm',
// other options here...
});
// Create a new class instance
const customFormatter = new CustomFormatter(locale, options);
// Use the shorthand methods
console.log(customerFormatter.m({ id: 'msg_id' }));
Constructor new IntlFmt(locale?: string, options: IntlFormatOptions): IntlFmt
locale
is optional, but must be defined if providing optionsoptions
can optionally be provided to modify behavior. Options include:initialNow: number | () => number
- the time value used for now when rendering dates and timesdefaultLocale: string
- the formatters default locale, defaults toen
defaultMessages: Object
- fallback messages to use if translated message, or message descriptor is not assigned to a messagedefaultFormats: Object
- the formatters default formats, defaults to{}
defaultOptions: {[methodName]: Object}
- assign default options used by each formatter methodformats: Object
- custom formats, defaults to{}
messages: { [id]: message }
- translated messages for the specified locale(s)requireOther: boolean
- true for ICU plural and select messages to require another
option (as defined in the ICU "spec"), defaults totrue
. Set this tofalse
for backward compatibility withreact-intl
.onError: (message: string, exception?: Error) => void
: A function to log errors, defaults writing toconsole.error
stringFormatFactory
: The factory used to createStringFormat
instances used to format message argument valuesmessageBuilderFactory
: The factory used to createMessageBuilder
instances used to formatmessage()
outputmessageBuilderContextFactory
: The factory used to createMessageBuilderContext
instances, passed to eachMessageBuilder
.
locale(): string
Returns the current locale.
now(): number
Returns the value being used to represent now
.
setNow(now?: number): void
Sets the value used to represent now
.
getRawMessage(msgDescriptor: MessageDescriptor): string
Returns the raw string value for the provided message descriptor
message(msgDescriptor: MessageDescriptor, values?: Object, options?: MessageOptions): mixed
Formats a message descriptor using the optionally assigned values.
htmlMessage(msgDescriptor: MessageDescriptor, values?: Object, options?: MessageOptions): mixed
Formats a HTML message descriptor using the optionally assigned values.
This exists for backwards compatibility only. Using this method is not recommended., use message()
instead.
date(value: any, options?: DateTimeFormatOptions): string
Formats a date for the current locale.
time(value: any, options?: DateTimeFormatOptions): string
Formats a time for the current locale.
number(value: any, options?: NumberFormatOptions): string
Formats a number for the current locale.
relative(value: any, options?: RelativeFormatOptions): string
Formats a relative time for the current locale, ie: 3 hours ago
.
plural(value: any, options?: PluralFormatOptions): string
Returns a value indicating the plurality of the value.
The return value will be one of zero, one, two, few, many, other
changeLocale(locale: string, options?: intlFormatOptionsType = {}): IntlFmt
Returns a new IntlFmt
instance, applying the defined locale and options.
The parent IntlFmt
instance values will be used where no options
as defined.
Intl Html Formatter
static extend(options: createFormatterOpts): IntlFmt
A factory method for creating new IntlFmt
classes that include custom shorthand method names.
Many i18n packages use either _()
or t()
for formatting translated messages. You can now use this factory method to assign your own shorthand syntax to the IntlFmt
class.
Define the createFormatterOpts:
message?: string
: The short method name formessage()
.messageElement?: string
: The short method name formessageElement()
.htmlMessage?: string
: The short method name forhtmlMessage()
.htmlMessageElement?: string
: The short method name forhtmlMessageElement()
.date?: string
: The short method name fordate()
.dateElement?: string
: The short method name fordateElement()
.time?: string
: The short method name fortime()
.timeElement?: string
: The short method name fortimeElement()
.number?: string
: The short method name fornumber()
.numberElement?: string
: The short method name fornumberElement()
.relative?: string
: The short method name forrelative()
.relativeElement?: string
: The short method name forrelativeElement()
.plural?: string
: The short method name forplural()
.
Example:
import {HtmlFormatter} from 'intl-fmt';
// Generate a new Formatter class
const CustomHtmlFormatter = HtmlFormatter.extend({
message: 'm',
messageElement: 'me',
// other options here
});
// Create a new class instance
const customFormatter = new CustomHtmlFormatter(locale, options);
// Use the shorthand methods
console.log(customerFormatter.m({ id: 'msg_id' }));
console.log(customerFormatter.me({ id: 'msg_id' }));
Constructor new HtmlFormatter(locale?: string, options: IntlHtmlFormatOptions): IntlFmt
locale
is optional, but must be defined if providing optionsoptions
can optionally be provided to modify behavior. Options include:initialNow: number | () => number
- the time value used for now when rendering dates and timesdefaultLocale: string
- the formatters default locale, defaults toen
defaultMessages: Object
- fallback messages to use if translated message, or message descriptor is not assigned to a messagedefaultFormats: Object
- the formatters default formats, defaults to{}
defaultOptions: {[methodName]: Object}
- assign default options used by each formatter methodformats: Object
- custom formats, defaults to{}
messages: { [id]: message }
- translated messages for the specified locale(s)requireOther: boolean
- true for ICU plural and select messages to require another
option (as defined in the ICU "spec"), defaults totrue
. Set this tofalse
for backward compatibility withreact-intl
.onError: (message: string, exception?: Error) => void
: A function to log errors, defaults writing toconsole.error
messageBuilderFactory
: The factory used to formatmessage
outputmessageBuilderContextFactory
: The factory used to createMessageBuilderContext
instances, passed to eachMessageBuilder
.defaultHtmlElement: string | (value) => mixed
- A string or function used to format all*Element()
methods. ie;span
will result in a formatted component being rendered as<span>value</span>
.htmlElements: { [formatMethodName]: string | (value) => mixed }
: An object of key/value pairs that define the element render configuration for specific formatter(s).htmlMessageBuilderFactory
: The factory used to formatmessageElement()
outputhtmlElementBuilderFactory
: The factory used to build HTML elements when thetagName
is a string.
locale(): string
Returns the current locale.
now(): number
Returns the value being used to represent now
.
setNow(now?: number): void
Sets the value used to represent now
.
message(msgDescriptor: MessageDescriptor, values?: Object, options?: MessageOptions): mixed
Formats a message descriptor using the optionally assigned values.
htmlMessage(msgDescriptor: MessageDescriptor, values?: Object, options?: MessageOptions): mixed
Formats a HTML message descriptor using the optionally assigned values.
This exists for backwards compatibility only. Using this method is not recommended., use message()
instead.
date(value: any, options?: DateTimeFormatOptions): string
Formats a date for the current locale.
time(value: any, options?: DateTimeFormatOptions): string
Formats a time for the current locale.
number(value: any, options?: NumberFormatOptions): string
Formats a number for the current locale.
relative(value: any, options?: RelativeFormatOptions): string
Formats a relative time for the current locale, ie: 3 hours ago
.
plural(value: any, options?: PluralFormatOptions): string
Returns a value indicating the plurality of the value.
The return value will be one of zero, one, two, few, many, other
messageElement(msgDescriptor: MessageDescriptor, values?: Object, options?: MessageOptions): mixed
Formats a message descriptor as a component.
htmlMessageElement(msgDescriptor: MessageDescriptor, values?: Object, options?: htmlMessageOptions): mixed
Formats a HTML message descriptor as a component.
This exists for backwards compatibility only. Using this method is not recommended, use messageComponent()
instead.
dateElement(value: any, options?: DateTimeComponentOptions): mixed
Formats a date for the current locale as a component.
timeElement(value: any, options?: DateTimeComponentOptions): mixed
Formats a time for the current locale as a component.
numberElement(value: any, options?: NumberComponentOptions): mixed
Formats a number for the current locale.
relativeElement(value: any, options?: RelativeComponentOptions): mixed
Formats a relative time for the current locale as a component, ie: <span>3 hours ago</span>
.
changeLocale(locale: string, options?: intlFormatOptionsType = {}): IntlHtmlFmt
Returns a new IntlHtmlFmt
instance, applying the defined locale and options.
The parent IntlHtmlFmt
instance values will be used where no options
as defined.
Tags
A tag
enables style placeholders to be included in the translation message without including any of the
style information in the translation message.
This provides 3 benefits:
- It decouples the styling of the text from the translations, allowing the styling to change independently of translations.
- It allows translation messages to retain context for text that will be styled
- Tags can be named to provide hints to translators
A tag must adhere to the following conventions:
- begin with
<x:
- The tag name can include only numbers, ascii letters, underscore and dot
.
. - must be closed, self-closing tags are supported but should be used sparingly as they can be confusing for translators
- Valid tag examples:
<x:0>hello</x:0>
<x:link>click me</x:link>
<x:emoji />
The tag value assigned to the .format()
method must be a function.
Using descriptive names for tag names can provide hints to translators about the purpose of the tags. Tags and arguments can be used in combination in ICU message formats.
The following example uses a {name}
argument in a tag.
import IntlFmt from 'intl-fmt';
const fmt = new IntlFmt();
const msgDescriptor = {
id: 'demo',
defaultMessage: 'Welcome back <x:bold>{name}</x:bold>'
};
const formattedMsg = fmt.message(msgDescriptor, {
bold: (content) => `<span class="boldText">${content}</span>`,
name: 'Bob'
});
console.log(formattedMsg); // Welcome back <span class="boldText">Bob</span>
Contribute
Check out the Contributing document for the details. Thanks!
For bugs or issues, please open an issue, and you're welcome to submit a PR for bug fixes and feature requests.
Before submitting a PR, ensure you run npm test to verify that your code adheres to the configured lint rules and passes all tests. Be sure to include unit tests for any code changes or additions.
License
This software is free to use under the Yahoo Inc. BSD license. See the LICENSE file for license text and copyright information.