Udostępnij za pośrednictwem


Building multilingual apps in PowerApps

PowerApps is localized in many languages - depending on the language of your computer, you'll see the authoring experience in the appropriate language (if the language is supported). For example, if I set my browser (Chrome) language to French, I'll see the authoring Studio in that language.

PowerApps Studio in French

If we want to make an app that can be viewed by its user in multiple locales, however, the Studio currently doesn't provide any easy way to have the messages shown to the user in their own language. This is a request that comes often in the forums (like one this week), so I'll show one way to accomplish that here.

Extracting strings

The first step in a multilingual app is to remove the "hardcoded" strings from it. That means that all text, messages, etc. that are shown to the user need to be taken out of the app.

Hard-coded resource strings

Notice that there are also strings that are not easily visible. Tooltips, hint texts, and others should also be considered. These are some of the places that have strings:

Many places with strings

One simple place to store those strings is in an Excel table - it's simple to edit, it can be imported directly into the app, and once in the app we can use functions to query it based on the user language. Here's an example of my translations (some of them came from an automated translation, so please forgive me if I'm butchering your language)

Once the Excel table is created, you can import it to your app - go to the View tab in the ribbon, select "Data sources" and "Add data source"; select then the option to add static data from Excel:

Add static Excel table

Now your app has all the strings that it will use loaded in memory; in my case I called the table 'Strings'.

Detecting the user language and fallback

We can get the language of the user via the Language function. That function can either simply return the language (e.g., "fr" for French) or it can also return additional information such as the region (such as "pt-BR" for Portuguese / Brazil) and the script (e.g., Serbian has two scripts: Cyrillic and Latin). For this post, I'll focus on the language only, and we need a formula to extract the language from whatever format the Language function can return.

But what you don't have translations for the user language? What is commonly done is to designate some of the languages to be the "fallback" language - one that will be used if the user's is not supported. And the formula to select the actual language to be used to lookup the translation from the table can start to get large, especially if it's going to be used in many places.

Since PowerApps currently doesn't support the concept of a macro (basically, an alias for a large expression), in those cases I use a hidden page, and store the result of the expression in a control, such as a label. For my app, I created
such a page and added a few labels to it as shown below (their names are shown in red):

Labels with language codes

Here are the formulas for those labels:
lblLanguage.Text: Language() lblLanguageOnly.Text: If("-" in lblLanguage.Text, Left(lblLanguage.Text, Find("-", lblLanguage.Text) - 1), lblLanguage.Text) lblUsedLang.Text: Coalesce(LookUp(Strings, lblLanguageOnly.Text = Lang).Lang, "en")

In the first label I store the language itself (mostly for my debugging purposes). The second label (lblLanguageOnly) looks at the value of the first label; if it has a '-' (meaning that it has more information that the language only) it strips down that part. The third label checks if the language of the user is supported. If it is, then the lookup will succeed and it will be returned by the Coalesce function. Otherwise, the LookUp function will return a blank value, and in this case I'm using English ("en") as the fallback language.

Retrieving the strings for the user language

Now we have the language that will be used (in the lblUsedLang.Text property), and the strings have already been imported. It's then time to go to the controls that display those strings to the user, and update their properties to look up the appropriate translation. We can do it using the LookUp function again. Here are the expressions for the contacts app that I showed in the beginning of this post:

LblAppName1.Text: LookUp(Strings, Key = "AppTitle" And Lang = lblUsedLang.Text, Value) TextSearchBox1.HintText: LookUp(Strings, Key = "SearchItemsHint" And Lang = lblUsedLang.Text, Value) NextArrow1.Tooltip: LookUp(Strings, Key = "ViewDetails" And Lang = lblUsedLang.Text, Value) IconNewItem1.Tooltip: LookUp(Strings, Key = "NewContactTooltip" And Lang = lblUsedLang.Text, Value)

And so on. The idea is that for all messages / strings that are shown to the user, a lookup will be made in the strings table. Here's my app when I run it in English:

App in English

And the same app in French:

App in French

Wrapping up

It's possible that in the future we'll add a native support for string / localization tables in PowerApps to make this process easier - and if you feel strongly about this feature, please create one / vote up an existing in the PowerApps Ideas board. This post shows one way to accomplish this scenario today, in case this is a mandatory requirement for the app that you're building.

As usual, let us know of any comments / questions you have by posting in our forums, we want to hear your feedback!