React-Intl — Message Formatting

Photo by bantersnaps on Unsplash

Many apps have to be made usable by different users from various parts of the world.

To make this easier, we can use the react-intl to do the internationalization for us.

In this article, we’ll look at how to get started with formatting messages with the react-intl library.

Message Syntax

We can format messages with placeholders and quantities.

For instance, we can write:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {
greeting: `Hello, {name}, you have {itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}.`
}
};
export default function App() {
const [name] = React.useState("james");
const [itemCount] = React.useState(20);
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage id="greeting" values={{ name, itemCount }} />
</p>
</IntlProvider>
);
}

to create a translation with the placeholders.

We have placeholder for name and itemCount .

The plural rules are defined by:

{itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}

Then we pass in the name and itemCount and they’ll be interpolated.

The id also has to be set.

Default Message

We can set the default message in the FormattedMessage component.

For instance, we can write:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {
greeting: `Hello, {name}.`
}
};
export default function App() {
const [name] = React.useState("james");
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage
id="greeting"
description="a greeting"
defaultMessage="Hello, {name}!"
values={{
name
}}
/>
</p>
</IntlProvider>
);
}

We have the defaultMessage prop which is overridden by the message that we defined.

If we remove the greeting message, then it’ll be used:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {}
};
export default function App() {
const [name] = React.useState("james");
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage
id="greeting"
description="a greeting"
defaultMessage="Hello, {name}!"
values={{
name
}}
/>
</p>
</IntlProvider>
);
}

We can also format the translated text with a function:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {}
};
export default function App() {
const [name] = React.useState("james");
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage
id="greeting"
description="a greeting"
defaultMessage="Hello, {name}!"
values={{
name
}}
>
{txt => <h1>{txt}</h1>}
</FormattedMessage>
</p>
</IntlProvider>
);
}

We have a function instead of nothing as the child of FormattedMessage so we’ll see an h1 heading instead of the default style.

Rich Text Formatting

We can divide the text into chunks and format it.

For instance, we can write:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {}
};
export default function App() {
const [name] = React.useState("james");
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage
id="greeting"
description="greeting"
defaultMessage="Hello, <b>{name}</b>"
values={{
b: (...chunks) => <b>{chunks}</b>,
name
}}
/>
</p>
</IntlProvider>
);
}

to format the bold text by returning our own component.

b is the tag name and it should match the message.

name has the value of the name placeholder.

It can be any XML tag.

We can have more complex formatting:

import React from "react";
import { IntlProvider, FormattedMessage } from "react-intl";
const messages = {
en: {}
};
export default function App() {
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedMessage
id="greeting"
defaultMessage="Go <a>visit our website</a> and <cta>read it</cta>"
values={{
a: (...chunks) => (
<a
class="external_link"
target="_blank"
rel="noopener noreferrer"
href="https://www.example.com/"
>
{chunks}
</a>
),
cta: (...chunks) => <b>{chunks}</b>
}}
/>
</p>
</IntlProvider>
);
}

We replace the a and cta tags with our own components.

FormattedDisplayName

We can format the display name with the FormattedDisplayName component.

For example, we can write:

import React from "react";
import { IntlProvider, FormattedDisplayName } from "react-intl";
const messages = {
en: {}
};
export default function App() {
return (
<IntlProvider locale="en" messages={messages.en}>
<p>
<FormattedDisplayName type="currency" value="USD" />
</p>
</IntlProvider>
);
}

We can pass in the type and value props to return the full name of the value .

Photo by Chandan Chaurasia on Unsplash

Conclusion

We can display translated and formatted text with the FormattedMessage component.

FormattedDisplayName lets us display the full name of languages and currencies.

Web developer. Subscribe to my email list now at https://thewebdev.info/subscribe/. Email me at hohanga@gmail.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store