Now that you've declared some messages, it's time to extract them.
Installation#
npm i -D @formatjs/cli
Extraction#
Add the following command to your package.json scripts:
{
"scripts": {
"extract": "formatjs extract"
}
}
and execute with npm:
npm run extract -- 'src/**/*.ts*' --ignore='**/*.d.ts' --out-file lang/en.json --id-interpolation-pattern '[sha512:contenthash:base64:6]'
ID Interpolation Pattern
Make sure this pattern matches idInterpolationPattern when you use babel-plugin-formatjs or @formatjs/ts-transformer in Bundling with formatjs or you'll get a MISSING_TRANSLATION error.
Given a file that has the following messages:
class PasswordChangeWithIntl extends React.Component {
render() {
const {intl} = this.props
return (
<li>
<input
placeholder={intl.formatMessage({
defaultMessage: 'New Password',
description: 'placeholder text',
})}
/>
<input
placeholder={intl.formatMessage({
id: 'explicit-id',
defaultMessage: 'Confirm Password',
description: 'placeholder text',
})}
/>
</li>
)
}
}
const PasswordChange = injectIntl(PasswordChangeWithIntl)
export function List(props) {
const intl = useIntl()
return (
<section>
<header>
<FormattedMessage
defaultMessage="Control Panel"
description="title of control panel section"
/>
</header>
<ul>
<li>
<button>
<FormattedMessage
defaultMessage="Delete user {name}"
description="Delete button"
values={{
name: props.name,
}}
/>
</button>
</li>
<PasswordChange />
</ul>
</section>
)
}
running the above command will create a file called lang/en.json:
{
"hak27d": {
"defaultMessage": "Control Panel",
"description": "title of control panel section"
},
"haqsd": {
"defaultMessage": "Delete user {name}",
"description": "delete button"
},
"19hjs": {
"defaultMessage": "New Password",
"description": "placeholder text"
},
"explicit-id": {
"defaultMessage": "Confirm Password",
"description": "placeholder text"
}
}
Message ID
During extraction, we'll preserve explicit declared IDs and insert a hash as an ID for messages without. We recommend against explicit IDs since it can cause collision.
Automatic ID Generation#
Since manual IDs are discouraged, we've provided a babel plugin and a TypeScript AST transformer that will automatically insert message IDs in your transpiled code. For more details please visit Bundling with formatjs.
Translation Management System (TMS) Integration#
The default format generated from @formatjs/cli might not work with the specific TMS/vendor you're working with. You can specify a custom formatter with --format <formatFile> that allows you to convert that format into something tailored to your TMS. For example:
If your vendor accepts the format like
{
"[id]": {
"string": "[message]",
"comment": "[description]"
}
}
you can run
npm run extract -- "src/**/*.{ts,tsx,vue}" --out-file lang/en.json --id-interpolation-pattern '[sha512:contenthash:base64:6]' --format formatter.js
where formatter.js is:
export function format(msgs) {
const results = {}
for (const [id, msg] of Object.entries(msgs)) {
results[id] = {
string: msg.defaultMessage,
comment: msg.description,
}
}
return results
}
We also provide several builtin formatters to integrate with 3rd party TMSes so feel free to create PRs to add more.
| TMS | --format |
|---|---|
| BabelEdit | simple |
| Crowdin Chrome JSON | crowdin |
| Lingohub | simple |
| Localize's Simple JSON | simple |
| Localizely | simple |
| locize | simple |
| Lokalise Structured JSON | lokalise |
| Phrase Strings | simple |
| POEditor Key-Value JSON | simple |
| SimpleLocalize JSON | simple |
| Smartling ICU JSON | smartling |
| Transifex's Structured JSON | transifex |