How to Localize the Text of Your Hosted Login Screens

In the article How to Modify the Text of Your Hosted Login Screens, we explained how you can change the text displayed on your Hosted Login screens. For example, the default screen displayed after a user successfully changes their password looks like this:

But what if you don’t like the heading Password Changed? That's OK; after all, by using the Identity Cloud Configuration APIs you can easily change your screen headings (or any other text that appears on your Hosted Login screens):

That's the sort of task detailed in How to Modify the Text of Your Hosted Login Screens.

However, what we didn’t do in the other article is tell you how you can localize your Hosted Login screens; that is, how can you provide options for displaying your screens in English, or Spanish, or Japanese, or any of the other languages and dialects supported by Hosted Login? Why didn’t we mention that in our other article? Because that’s what this article is for.

Before we get into the nitty-gritty details, we need to provide you with an overview of how Hosted Login handles different locales. For starters, by using the ui_locales parameter you can specify the language used on your Hosted Login screens. There’s just one catch, however. For example, suppose you set ui_locales to French as spoken in Canada (fr-CA). If you do that, and if Canadian French is one of your configured locales, here’s what your Hosted Login sign-in screen will look like:

We’re guessing that’s not the look you were aiming for.

We’ll explain what the problem is, and how to fix it, in just a minute. First, however, we need to clarify something. A few paragraphs ago we said, “If you do that, and if Canadian French is one of your configured locales ….” Does it really matter whether or not Canadian French (fr-CA) is one of your configured locales? As it turns out, it does. For example, suppose that Hindi (as spoken in India) is not one of your configured locales; that is, there’s no hi-IN locale anywhere in the flow used by your Hosted Login application client. So what happens if you set the ui_locales parameter to Hindi (hi-IN)? This is what happens:

That’s an improvement over our French screen, but it doesn’t really look like Hindi. What’s the deal here?

The deal here is this: if you specify an invalid locale (invalid meaning a locale that isn't defined in your flow), Hosted Login reverts to displaying your screens in English, the default language. In our example flow, at least, Hindi is an invalid locale: it's not defined anywhere. Consequently, Hosted Login ignores the ui_locales parameter and displays your screens in English.

However, Canadian French is a valid locale: we have an fr-CA locale in the flow:

[
    {
        "_self": "/config/hevwjvt8j7cym5hbbzdu8mv6aj/flows/documentation/locales/it-IT",
        "name": "it-IT"
    },
    {
        "_self": "/config/hevwjvt8j7cym5hbbzdu8mv6aj/flows/documentation/locales/en-US",
        "name": "en-US"
    },
    {
        "_self": "/config/hevwjvt8j7cym5hbbzdu8mv6aj/flows/documentation/locales/fr-CA",
        "name": "fr-CA"
    }
]

Because of that, Hosted Login tries to display our screens in French. And yet, our sign-in screen showed up without any text, French or otherwise. Like we said before, what’s the deal here?

Note. Good question: how do you know which locales are available for a given flow? One way is to use the /config//flows//locales endpoint, which returns information about the locales associated with a flow. For example, the documentation flow referenced in this API response above shows three locales (Italian, English, and French):

Which means that now we can explain why the Canadian French sign-in screen showed up without any text. As noted in How to Modify the Test of Your Hosted Login Screens, the text used on your screens is defined in the flow as a set of translations. For example, if you look at the translations section of the flow, you’ll see a subsection for the en-US locale. As you can also see, each translation key (e.g., 3df2ee0a29281d27b9c7bcd94a6a0fd9) has a text value associated with it:

That text value is the text that appears on your Hosted Login screens.

And that’s great when working with the en-US locale: with one or two exceptions, the Identity Cloud supplies predefined values for your English translations. However, if you look at the translations for any of your other locales, you're unlikely to see that any of these translation keys have defined values:

Note. Yes, that's the expected behavior: Akamai only supplies en-US translations. If you want translations for different locales you must provide them yourself. And what if your flow doesn’t have a locale that you need? No problem; see Adding a New Locale to Your Flow at the end of this article.

This is the problem. We asked Hosted Login to display our screens using French text values, and it did. Unfortunately, however, all the French text values are empty strings. Because of that, there’s no text to display. That’s why Hosted Login displayed a bunch of empty strings. Hosted Login dutifully displays whatever text is associated with a translation key, even if that means displaying no text at all:

And if you’re thinking what we’re thinking then you’re right: to display our Hosted Login screens in French (or, in our case, fr-CA) we need to provide values for all the relevant translations. And, needless to say, we need to provide French values for all the relevant translations.

To do that, we just have to follow the same process we followed in the article about modifying Hosted Login screen text; the only difference is that, this time around, we need to change the translation values for the fr-CA locale. That means making an API call similar to this one:

curl -X PATCH \
'https://v1.api.us.janrain.com/config/79y4mqf2rt3bxs378kw5479xdu/flows/testFlow/translations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic eTR4Zmc2ZjQ0bXNhYzN2ZXBqanZ4Z2d6dnQzZTNzazk6OTVjY3hrN2N6YnZ1eng2ZHB0ZTVrOXA2ZGo1Ynpla3U=' \
--d '
[
    {
          "key": "1e59da274168d41a840d66aeccd0ecc8",
          "values": {
               "fr-CA": "Bienvenue chez Gizmo!"
          }
     }
]'
Note. Unlike some of the Configuration API endpoints, you don’t have to include all your translations when making a change: translations that aren’t included in the body parameter will not be deleted. That’s because this endpoint uses the PATCH method instead of the PUT method.

The preceding API call is designed to change the fr-CA translation key associated with the text Welcome to Gizmo! (translation key 1e59da274168d41a840d66aeccd0ecc8). If we look in the flow, we’ll see that that’s exactly what happened:

And if we now set ui_locales to fr-CA we’ll see that our new translation appears onscreen:

That’s a little more like it. We’re still missing a lot of text, but we’ve proven that we can localize a Hosted Login screen.

In fact, to get a truly French sign-in screen, all we have to do is to make sure we provide translations for each text element used on that screen. This API call does that very thing:

curl -X PATCH \
'https://v1.api.us.janrain.com/config/79y4mqf2rt3bxs378kw5479xdu/flows/testFlow/translations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic eTR4Zmc2ZjQ0bXNhYzN2ZXBqanZ4Z2d6dnQzZTNzazk6OTVjY3hrN2N6YnZ1eng2ZHB0ZTVrOXA2ZGo1Ynpla3U=' \
--d '
[
    {
          "key": "1e59da274168d41a840d66aeccd0ecc8",
          "values": {
               "fr-CA": "Bienvenue chez Gizmo!"
          }
     },
    {
          "key": "396cebd8cfcaddcd9cb3d9680887511b",
          "values": {
               "fr-CA": "Connectez-vous pour profiter de tous les avantages de ce site Web fantastique."
          }
     },
    {
          "key": "a08db6bdc846bbdc2ba6413dccc8eaad",
          "values": {
               "fr-CA": "Ou connectez-vous par e-mail"
          }
     },
    {
          "key": "483ebfcbd0601afa1f2046c2b5ac48c9",
          "values": {
               "fr-CA": "Adresse e-mail"
          }
     },
    {
          "key": "863865dd78ba0fd0d83bc8e9e0c03dd1",
          "values": {
               "fr-CA": "Mot de passe"
          }
     },
    {
          "key": "11c5e0a55aeb2a859cabeea11df10bf4",
          "values": {
               "fr-CA": "Mot de passe oublié?"
          }
     },
    {
          "key": "9fdf2c17900ac5fc2eb21ddf08f0a22c",
          "values": {
               "fr-CA": "Se connecter"
          }
     },
    {
          "key": "9d5a4a4254ec1a76fc701f9addc33ef6",
          "values": {
               "fr-CA": "Pas un membre?"
          }
     },
    {
          "key": "2934cb450d1559245729bdca7f739b9f",
          "values": {
               "fr-CA": "Ouvrez un compte."
          }
     },
    {
          "key": "1f3612202bb6d9bc287448ce2ea35a02",
          "values": {
               "fr-CA": "Demande d'\''annulation"
          }
     },
    {
          "key": "22e2a5e5a6ac5038cf3e8841b99a66c7",
          "values": {
               "fr-CA": "Besoin d'\''aide?"
          }
     },
    {
          "key": "12ed346de096c8dd8f5407ad1aa4aaa6",
          "values": {
               "fr-CA": "Visitez notre centre d'\''aide."
          }
     }
]'

And here’s what our all-French sign-in screen looks like:

Not bad. Or, as the French would say, pas mal. (Assuming, of course, that they’re French people who rely on Google Translate for their translations).

Adding a Locale to a Flow

Localizing your Hosted Login screens is actually fairly easy (although, it will obviously take a little time and effort to localize all your Hosted Login screens). At first glance, however, that might seem to be a case of easier said than done. For example, the flow used by the documentation team includes three locales:

  • en-US (US English)
  • fr-CA (Canadian French)
  • he (Hebrew)

That’s fine, but suppose we want to localize our screens in Italian. How do we add an Italian locale (it-IT) to the flow? After all, a careful perusal of the Identity Cloud Configuration APIs doesn’t appear to include a method/endpoint that creates a new locale.

And that’s true: there’s no obvious way to add a new locale to a flow. But that doesn’t mean that it can’t be done, and that it can’t be done with very little effort on your part. And here's how you go about doing that.

Suppose we want to add the it-IT (Italian) locale to our flow. To do that, all we have to do is set at least one translation key to Italian. For example, in our flow we have a translation key (9977e57d-2d15-4221-a336-930731e14e8b) where the English text is set to Country of Residence. Even though we don’t have an it-IT locale in the flow, we can still make an API call that specifies a value for the Italian version of 9977e57d-2d15-4221-a336-930731e14e8b:

curl -X PATCH 'https://v1.api.us.janrain.com/config/79y4mqf2rt3bxs378kw5479xdu/flows/testFlow/translations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic eTR4Zmc2ZjQ0bXNhYzN2ZXBqanZ4Z2d6dnQzZTNzazk6OTVjY3hrN2N6YnZ1eng2ZHB0ZTVrOXA2ZGo1Ynpla3U=' \
--d '[
    {
          "key": "9977e57d-2d15-4221-a336-930731e14e8b",
          "values": {
               "it-IT":"Paese di Residenza"
          }
     }
]
'

That API call creates a brand-new it-IT locale for us, and sets the value of 9977e57d-2d15-4221-a336-930731e14e8b to boot:

That’s all it takes. From here, we can now define Italian translations for any of the translation keys in the flow.