Process string messages for translation from modules that use react-intl, specifically:
- Parse and verify that messages are ICU-compliant w/o any syntax issues.
- Remove
descriptionfrom message descriptor to save bytes since it isn't used at runtime. - Option to remove
defaultMessagefrom message descriptor to save bytes since it isn't used at runtime. - Automatically inject message ID based on specific pattern.
Installation#
npm i babel-plugin-formatjs
Usage#
This Babel plugin only visits ES6 modules which import React Intl.
The default message descriptors for the app's default language will be processed from: defineMessages(), defineMessage(), intl.formatMessage and <FormattedMessage>; all of which are named exports of the React Intl package.
Via babel.config.json (Recommended)#
babel.config.json
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"ast": true
}
]
]
}
Via Node API#
The extract message descriptors are available via the metadata property on the object returned from Babel's transform() API:
transform('code', {
plugins: ['formatjs'],
}) // => { code, map, ast, metadata['formatjs'].messages, metadata['formatjs'].meta };
Options#
overrideIdFn#
A function with the signature (id: string, defaultMessage: string, description: string|object) => string which allows you to override the ID both in the extracted javascript and messages.
idInterpolationPattern#
If certain message descriptors don't have id, this pattern will be used to automaticallygenerate IDs for them. Default to [sha512:contenthash:base64:6]. See nodejs crypto createHash for hash algorithms & nodejs buffer docs for digest encodings.
removeDefaultMessage#
Remove defaultMessage field in generated js after extraction.
additionalComponentNames#
Additional component names to extract messages from, e.g: ['FormattedFooBarMessage'].
This option is useful for creating wrapper components that have react-intl functionality built in. For example, if you have a custom button component that internally uses formatMessage:
// Your wrapper component - must accept same props as FormattedMessage
function CustomButton({id, defaultMessage, description, values, onClick}) {
const intl = useIntl()
return (
<button onClick={onClick}>
{intl.formatMessage({id, defaultMessage, description}, values)}
</button>
)
}
// Usage - this will be extracted when CustomButton is in additionalComponentNames
;<CustomButton
defaultMessage="Click me"
description="Button text"
onClick={handleClick}
/>
Configuration:
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"additionalComponentNames": ["CustomButton"]
}
]
]
}
NOTE: By default we check for the fact that FormattedMessage is imported from moduleSourceName to make sure variable alias works. This option does not do that so it's less safe - any component with the specified name will be processed regardless of where it's imported from.
For a complete guide on creating wrapper components with auto ID generation, see the Wrapper Components Guide.
additionalFunctionNames#
Additional function names to extract messages from, e.g: ['$formatMessage'].
This option is useful when you want to create custom function wrappers around formatMessage, or use shorter aliases. For example:
// Custom translation hook - wrapper must match formatMessage signature
function useTranslation() {
const intl = useIntl()
const t = (descriptor, values) => intl.formatMessage(descriptor, values)
return {t}
}
// Usage - this will be extracted when 't' is in additionalFunctionNames
function MyComponent() {
const {t} = useTranslation()
return (
<div>{t({defaultMessage: 'Hello world', description: 'Greeting'})}</div>
)
}
Configuration:
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"additionalFunctionNames": ["t", "$formatMessage"]
}
]
]
}
For a complete guide on creating function wrappers with auto ID generation, see the Wrapper Components Guide.
pragma#
parse specific additional custom pragma. This allows you to tag certain file with metadata such as project. For example with this file:
// @intl-meta project:my-custom-project
<FormattedMessage defaultMessage="foo" id="bar" />
and with option {pragma: "@intl-meta"}, we'll parse out // @intl-meta project:my-custom-project into {project: 'my-custom-project'} in the result file.
ast#
Pre-parse defaultMessage into AST for faster runtime perf. This flag doesn't do anything when removeDefaultMessage is true.
preserveWhitespace#
When set to true, message trimming is disabled.
flatten#
Whether to hoist selectors & flatten sentences as much as possible. For example:
I have {count, plural, one{a dog} other{many dogs}}
becomes
{count, plural, one{I have a dog} other{I have many dogs}}
The goal is to provide as many full sentences as possible since fragmented sentences are not translator-friendly. This transformation is applied before ID generation when using overrideIdFn or idInterpolationPattern, ensuring the ID is based on the flattened message format.