We do not like this clutter:

const name = 'John Doe'; <FormattedMessage

id="welcome"

defaultMessage={`Hello {name}!`}

values={{ name: <b>{name}</b> }}

/>

While react-intl works awesome having those FormattedMessage everywhere does not really help keeping your code nice and readable. Wouldn’t it be nicer you just could write:

<FormattedMessage id=”welcome”>Hello <b>{name}</b>!</FormattedMessage>

babel macros to the rescue

You could easily write a babel plugin to transform the above simplified markup to the needed react-intl FormattedMessage. But there is a better way using Kent C. Dodds babel macros (https://github.com/kentcdodds/babel-plugin-macros). There comes a big advantage with using macros (beside they are super simple to create) you can use those with applications created with create-react-app without ejecting (on time of writing needs an alpha build v2.x.x).

A babel macro is basically just a function that gets a reference of the nodes using the macro:

const { createMacro } = require('babel-plugin-macros') module.exports = createMacro(myMacro) function myMacro({references, state, babel}) {

// the FormattedMessage imported in below code snippet

const { FormattedMessage = [] } = references; // transform each occurance

FormattedMessage.forEach(referencePath => { /* transform */ });

}

We won’t go through all the details of the macro used to transform the simpler markup — but you can checkout the code here:

You can use the macro like:

// import the macro component

import { FormattedMessage } from "./intl.macro"; // and use it

<FormattedMessage id=”welcome”>Hello <b>{name}</b>!</FormattedMessage>

The macro will transform it to the react-intl FormattedMessage:

<FormattedMessage

id="welcome"

defaultMessage={`Hello {name}!`}

values={{ name: <b>{name}</b> }}

/>

Plurals and Select

We could add some more macro magic to also simpler plurals and selects:

import { Select, Plural } from "./intl.macro"; // select

<FormattedMessage

id="avoid_bugs"

defaultMessage="{gender,select,he{He avoids bugs.}she{She avoids bugs.}other{They avoid bugs.}}"

values={{ count: 10 }}

/> // will become

<Select

id="avoid_bugs"

switch={gender}

male="He avoids bugs."

female="She avoids bugs."

other="They avoid bugs."

/> // plurals

<FormattedMessage

id="items_count"

defaultMessage="{count,plural,=0{There is no item.}one{There is # item.}other{There are # items.}}"

values={{ count: 10 }}

/> // will become:

<Plural

id="items_count"

count={itemsCount1}

$0="There is no item."

one="There is # item."

other="There are # items."

/>

For more options (like nesting components) have a look at the sample usages: