When localizing your app, you may need to display text in the user's chosen language. Users can set different languages for different interfaces. For example, they may choose one language for the dashboard, but allow their site users to set a different language for the site. This means your app needs to retrieve the chosen settings for each extension.
The essentials SDK's i18n
submodule allows app extensions to access the active language and locale settings of a site's interfaces.
This article outlines the recommended steps for using the SDK to display localized text in different parts of your app.
Note: This article uses the FormatJS' react-intl
package, but you may use any other localization library. Make sure to install your chosen package in your app before starting to code.
For each language your app supports, create a JSON file containing all your app's strings.
Notes:
{}
represents variables. The Intl MessageFormat uses ICU message syntax and CLDR locale data.For example, to support English and Spanish, create 2 JSON files:
src/intl/messages/en.json
src/intl/messages/es.json
Create and export a helper function that loads the correct messages JSON based on the extension's language:
src/intl/load-messages.js
.i18n
from @wix/essentials
:
i18n.getLanguage()
and returns the correct messages JSON based on the language retrieved.
At the end of this step, your file should look similar to this:
src/intl/load-messages.js
intl
This step is implemented differently depending on whether your app's extensions use React or plain JavaScript.
Render your extensions using the IntlProvider
component from the react-intl
package.
To avoid repeating this code for each of your apps' extension, create a higher order component (HOC) that you can use to wrap your extensions with IntlProvider
:
withIntlProvider
. This is your HOC that will wrap your extensions with IntlProvider
.useEffect()
, when the component loads, call loadMessages()
that you defined in Step 2, and then save the response in your state variable.loadMessages()
doesn't return a value, the component should return null
.IntlProvider
component with the following props:
messages
prop.i18n.getLocale()
to the locale
prop.<Component {...props} />
as the children prop.At the end of this step, your file should look like this:
src/intl/withIntlProvider.jsx
You will need an intl
object instance to format your messages.
To create this instance:
src/intl/create-intl.js
and add the following import statements:
createIntl
.createIntl
function should return the result of calling createIntlCore()
and passing the following parameters.
locale
: Use the value returned by i18n.getLocale()
.messages
: Use the value returned by loadMessages()
, defined in Step 2.creatIntlCache()
;At the end of this step, your file should look like this:
src/intl/create-intl.js
Retrieve and render localized text.
This step is implemented differently depending on whether your app's extensions use React or plain JavaScript.
To display localized code, wrap your extension with the withIntlProvider()
function that you defined in Step 3, and use the FormattedMessage
component to display your text.
Note: You only need to wrap the components in your extension that need to access the localized text. However, wrapping your main app extension component with withIntlProvider()
makes further development smoother.
The following example uses FormattedMessage
with the following props:
id
: The key of the message you want to render from your JSON file.defaultMessage
: The message to render if no message is retrieved.values
: An object of the variable values to use in the message.src/dashboard/pages/page.tsx
To display localized code:
createIntl()
function that you defined in Step 3 to create an intl
instanceformatMessage
property to return your translated text.For example:
src/site/embedded-scripts/my-script/index.ts