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]'

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"
  }
}

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.