---
myst:
html_meta:
"description": ""
"property=og:description": ""
"property=og:title": ""
"keywords": ""
---
(i18n-label)=
# Internationalization
## Making Text Translatable
Volto uses `react-intl` to translate strings.
We start by importing the component:
```jsx
import { FormattedMessage } from 'react-intl';
```
Then we can use the `FormattedMessage` component to translate a string:
```jsx
```
## Extracting i18n Strings
Volto provides an i18n extraction script to get all translatable strings from your application.
Run the following:
```shell
yarn i18n
```
This will generate the following output:
```console
Extracting messages from source files...
Synchronizing messages to pot file...
Synchronizing messages to po files...
Generating the json files...
done!
```
As the description suggests it will first extract all messages from the source files into a `.json` file.
Then it will synchronize the extracted messages with the `.pot` master file and with all the `.po` files found in the project.
After that it will generate the final `.json` files which are used in the application.
If you want to translate the strings edit the `.po` files and run the script again.
This script will combine the messages located in Volto itself and the current project, and combine them into the `.json` files.
## Exercise
Translate the `Tags:` label which was added in the previous chapter to Dutch and German.
````{dropdown} Solution
:animate: fade-in-slide-down
:icon: question
```jsx
/**
* Tags component.
* @module components/theme/Tags/Tags
*/
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { Container } from 'semantic-ui-react';
import { FormattedMessage } from 'react-intl';
/**
* Tags component class.
* @function Tags
* @param {array} tags Array of tags.
* @returns {string} Markup of the component.
*/
const Tags = ({ tags }) =>
tags && tags.length > 0 ? (
:
{tags.map(tag => (
{tag}
))}
) : (
);
/**
* Property types.
* @property {Object} propTypes Property types.
* @static
*/
Tags.propTypes = {
tags: PropTypes.arrayOf(PropTypes.string),
};
/**
* Default properties.
* @property {Object} defaultProps Default properties.
* @static
*/
Tags.defaultProps = {
tags: null,
};
export default Tags;
```
````
## Translate Attributes
When you want to translate attributes you can't use the `FormattedMessage` component since it will generate markup.
In order to translate a normal string or attribute you can use the `formatMessage` method of `react-intl`.
First you need to import all the required methods:
```jsx
import { defineMessages, injectIntl, intlShape } from 'react-intl';
```
Then you can use the `defineMessages` method to define your messages:
```jsx
const messages = defineMessages({
site: {
id: 'Site',
defaultMessage: 'Site',
},
});
```
In order to use the `formatMessage` method you have to inject the `intl` object into your class or function.
For pure functions you can use:
```jsx
export default injectIntl(Logo);
```
And for classes you can use:
```jsx
@injectIntl
class Logo extends Component {
}
```
You can use the provided `PropType` as follows:
```{code-block} jsx
:emphasize-lines: 3
Tags.propTypes = {
tags: PropTypes.arrayOf(PropTypes.string),
intl: intlShape.isRequired,
};
```
Now we can use the method like this:
```jsx
```
## Exercise
Add a title to the tag links with the message `Search for tag {tag}`.
````{dropdown} Solution
:animate: fade-in-slide-down
:icon: question
```jsx
/**
* Tags component.
* @module components/theme/Tags/Tags
*/
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { Container } from 'semantic-ui-react';
import {
defineMessages,
injectIntl,
intlShape,
FormattedMessage,
} from 'react-intl';
const messages = defineMessages({
searchTag: {
id: 'Search for tag {tag}',
defaultMessage: 'Search for tag {tag}',
},
});
/**
* Tags component class.
* @function Tags
* @param {array} tags Array of tags.
* @returns {string} Markup of the component.
*/
const Tags = ({ tags, intl }) =>
tags && tags.length > 0 ? (
:
{tags.map(tag => (
{tag}
))}
) : (
);
/**
* Property types.
* @property {Object} propTypes Property types.
* @static
*/
Tags.propTypes = {
tags: PropTypes.arrayOf(PropTypes.string),
intl: intlShape.isRequired,
};
/**
* Default properties.
* @property {Object} defaultProps Default properties.
* @static
*/
Tags.defaultProps = {
tags: null,
};
export default injectIntl(Tags);
```
````