Building multilingual apps in PowerApps
Want to make your app more accessible to users and available in multiple languages? Inspired by a forum inquiry posted by our community member Pabloceka, Senior Software Design Engineer Carlos Figueira shares his take on how you can use an Excel table that stores all the translations, and then performs lookups on those translations.
Check it out his detailed steps below!
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.
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.
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.
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:
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:
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):
Here are the formulas for those labels:
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 functionwill 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:
And the same app in French:
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!