Translating UI Components
The messages returned by the polyglotI18nProvider
function argument should be a dictionary where the keys identify interface components, and values are the translated string. This dictionary is a simple JavaScript object looking like the following:
{
ra: {
action: {
delete: 'Delete',
show: 'Show',
list: 'List',
save: 'Save',
create: 'Create',
edit: 'Edit',
cancel: 'Cancel',
},
...
},
}
All react-admin core components use keys starting with the ra
prefix, to prevent collisions with your own custom translations.
The default (English) messages are available in the ra-language-english
package source.
Tip: You can see the raw translation keys in the UI by passing a dummy i18nProvider
to the <Admin>
component:
const i18nProvider = {
translate: key => key,
changeLocale: locale => Promise.resolve(),
getLocale: () => 'en',
}
const App = () => (
<Admin
dataProvider={dataProvider}
i18nProvider={i18nProvider}
>
{/* ... */}
</Admin>
);
Translating Resource and Field Names
When react-admin needs to render a resource name (“post”, “comment”, etc.) or a field name (“title”, “first_name”, etc.), it “humanizes” the technical identifier to make it look better (e.g. “first_name” becomes “First name”).
However, before humanizing names, react-admin checks the messages
dictionary for a possible translation, with the following keys:
resources.${resourceName}.name
for resource names (used for the menu and page titles)resources.${resourceName}.fields.${fieldName}
for field names (used for datagrid header and form input labels)
This lets you customize resource and field names for each locale.
Create an object containing the translation messages for your app resource and field names:
// in src/i18n/en.js
import englishMessages from 'ra-language-english';
export const en = {
...englishMessages,
resources: {
shoe: {
name: 'Shoe |||| Shoes',
fields: {
model: 'Model',
stock: 'Nb in stock',
color: 'Color',
},
},
customer: {
name: 'Customer |||| Customers',
fields: {
first_name: 'First name',
last_name: 'Last name',
dob: 'Date of birth',
}
}
},
...
};
What’s with the strange ||||
syntax? ra-i18n-polyglot
comes with a pluralization system allowing to define both singular and plural translations for a key. It even works for languages with more than one plural form (like Slavic languages)!
Tip: Providing translation for resource and field names using the i18nProvider
is an alternative to using the label
prop in Field and Input components, with the advantage of supporting translation.
Translating Custom Components
If you need to translate messages in your own components, React-admin provides the useTranslate
hook, which returns the translate
function.
Imagine a translation key for the text to translate, e.g. ‘myroot.hello.world’ for a ‘Hello, World’ button, and call the translate
function with this key:
// in src/MyHelloButton.js
import * as React from "react";
import { useTranslate } from 'react-admin';
export const MyHelloButton = () => {
const translate = useTranslate();
return (
<button>{translate('myroot.hello.world')}</button>
);
};
Tip: For your message identifiers, choose a different root name than ra
and resources
, which are reserved.
Then, in your translation messages, define the translation for the key ‘myroot.hello.world’:
// in src/i18n/en.js
import englishMessages from 'ra-language-english';
export const en = {
...englishMessages,
myroot: {
hello: {
world: 'Hello, World',
},
},
...
};
Tip: Don’t use useTranslate
for Field and Input labels, or for page titles, as they are already translated:
// don't do this
<TextField source="first_name" label={translate('myroot.first_name')} />
// do this instead
<TextField source="first_name" label="myroot.first_name" />
// or even better, use the default translation key
<TextField source="first_name" />
// and translate the `resources.customers.fields.first_name` key
Translating Form Validation Errors
In Create and Edit views, forms can use custom validators. These validator functions should return translation keys rather than translated messages. React-admin automatically passes these identifiers to the translation function.
For instance, here is a validator function that only allows numbers greater than 10:
// in validators/required.js
const greaterThanTen = (value, allValues, props) =>
value <= 10
? 'myroot.validation.greaterThanTen'
: undefined;
// in PersonEdit.js
const PersonEdit = () => (
<Edit>
<SimpleForm>
<TextInput source="name" />
<TextInput source="age" validate={greaterThanTen} />
</SimpleForm>
</Edit>
);
// in i18n/en.json
export default {
myroot: {
validation: {
greaterThanTen: 'Should be greater than 10',
}
}
};
If the translation depends on a variable, the validator can return an object rather than a translation identifier:
// in validators/minLength.js
const minLength = (min) => (value, allValues, props) =>
value.length < min
? { message: 'myroot.validation.minLength', args: { min } }
: undefined;
// in i18n/en.js
export default {
myroot: {
validation: {
minLength: 'Must be %{min} characters at least',
}
}
};
Translating Notification Messages
If you use the useNotify
hook to display a notification to the user, you can use a translation key for the notification text. React-admin will translate it automatically - no need to call translate
.
const ValidateCommentButton = ({ id }) => {
const notify = useNotify();
const [update] = useUpdate();
const handleClick = () => {
update(
'comments',
{ id, data: { status: 'approved' } },
{ onSuccess: () => notify('myroot.comments.validate.success') }
);
};
return <button onClick={handleClick}>Validate</button>;
}
Interpolation, Pluralization and Default Translation
If you’re using ra-i18n-polyglot
(the default i18nProvider
), you can leverage the advanced features of its translate
function. Polyglot.js, the library behind ra-i18n-polyglot
, provides some nice features such as interpolation and pluralization, that you can use in react-admin.
const messages = {
'hello_name': 'Hello, %{name}',
'count_beer': 'One beer |||| %{smart_count} beers',
};
// interpolation
translate('hello_name', { name: 'John Doe' });
=> 'Hello, John Doe.'
// pluralization
translate('count_beer', { smart_count: 1 });
=> 'One beer'
translate('count_beer', { smart_count: 2 });
=> '2 beers'
// default value
translate('not_yet_translated', { _: 'Default translation' });
=> 'Default translation'
Check out the Polyglot.js documentation for more information.
Translating Record Content
Some of your records may contain data with multiple versions - one for each locale.
For instance, a product may have one reference, but several names. A product
record would look like this:
{
id: 123,
reference: 'GURSIKSO',
name: {
en: 'Evening dress',
fr: 'Robe du soir',
}
}
React-admin provides a specialized component to display such translatable data (<TranslatableFields>
), and another specialized component to edit it (<TranslatableInputs>
):
import { Edit, SimpleForm, TextInput, TranslatableInputs } from 'react-admin';
export const ProductEdit = () => (
<Edit>
<SimpleForm>
<TextInput source="reference" />
<TranslatableInputs locales={['en', 'fr']}>
<TextInput source="name" />
</TranslatableInputs>
</SimpleForm>
</Edit>
);
Check the documentation for each of these components for details.
Forcing The Case in Confirm messages and Empty Page
In confirmation messages and on the empty page, the resource name appears in the middle of sentences, and react-admin automatically sets the resource name translation to lower case.
Are you sure you want to delete this comment?
This works in English, but you may want to display resources in another way to match with language rules, like in German, where names are always capitalized.
Sind Sie sicher, dass Sie diesen Kommentar löschen möchten?
To do this, simply add a forcedCaseName
key next to the name
key in your translation file.
{
resources: {
comments: {
name: 'Kommentar |||| Kommentare',
forcedCaseName: 'Kommentar |||| Kommentare',
fields: {
id: 'Id',
name: 'Bezeichnung',
}
}
}
}