Build multi-lingual Actions for the Google Assistant

Credits: ©

Time has come for your Action to go international. In this post, we will learn how to localize our apps for the Google Assistant to provide customized experiences for different languages and locales.

Before we begin

Before we start localizing our Actions for the Google Assistant, we need to make sure to check what are the currently supported languages by the Google Assistant. You can find an up to date list in the Assistant documentation.

Localizing our Agent

Before we dive in, it’s important to note that localizing an Action for the Google Assistant is done in 3 steps:

  1. Localize the Agent (intents and entities) in DialogFlow—during the design phase.
  2. Handle and localize responses from fulfillments (webhook)—during the development phase.
  3. Provide a localized information for the Action before publishing it to the Application Directory.

In order to showcase these steps, let’s use an existing Action I’ve built, which only supports English and make it also available in French.

Localizing the “Intents”

For simplicity, this Action has only one intent which we’ll need to localize. However, in real world use cases, we usually have tens—if not hundreds of intents. You will have to localize all of them!

In our simple case, we only have a “read” intent with two utterances:

  1. “read this text”
  2. “extract the text”

So, to add new languages, let’s click on the “+” near the language name (on the left panel), and choose the new language we would like to add—French in our case:

In some use cases, you can also add a localized version of each main language. For instance, if the main language is French, you might want to provide an European French or Canadian French based on the users you are targeting—This completely optional, of course. If that is your case, here is how you can achieve this:

To add a locale, let’s simply hover the mouse over the French main language and click on the “+ Add locale” blue label, then select a locale:

All the new locales will be listed under their main language:

When you’re done, you can access the new language and its locales from the language section, on the left panel:

Now you’re ready to localize the user’s utterances, for each intent!

Just make sure you select the correct language (or locale) before you start: The blue label indicates the currently active language (or locale).

Localizing “entities”

If your Action contains entities, you will have to localize them as well. When localizing entities, you just need to localize the values (the second column). Make sur you keep the tokens (the first column) identical across all of your locales:

Localizing the responses

If you do provide static responses (from DialogFlow), you obviously need to localize them as well:


In most use cases, you probably have the business logic of your Action hosted on the server side—and have configured a webhook for that. In this case, you will need to provide the right response based on the user’s locale. In fact, when the user interacts with your Action, you receive the Google Assistant locale setting in each request to your fulfillment—this setting is based on the user’s phone main language. You can then use this locale, e.g. fr-FR, to figure out how to return different responses based on a user's language or locale.

After having built dozens of Actions, I’ve come up with a small utility Node package that handles that process for you.

First, you need to install the package using Npm or Yarn:

$ yarn add @manekinekko/actions-on-google-i18n

Before using this package, you need to create a file for each locale that you provide. The filename MUST follow the IETF language tag format, e.g. en-US or fr-FR:

├── src/
│ ├── locales/
│ │ ├── fr-FR.json
│ │ ├── fr-CA.json
│ │ ├── en-US.json
│ │ └── en-GB.json

Each file MUST comply with the following format:

  • A unique key identifying a unique string.
  • A value which contains the text that will be sent to the user. You can use SSML.
  • You can use variables inside the string by wrapping them in {varibale_name}.
// src/locales/en-US.json
"MSG_001": "Hi {name}. What can I do for ya?"
// src/locales/en-GB.json
"MSG_001": "Hi {name}. How can I help?"
// src/locales/fr-FR.json
"MSG_001": "Salut {name}. Que puis-je faire?"

Next, go ahead and import the package into your Action function and call the configure method as follows:

const i18n = require("@manekinekko/actions-on-google-i18n");
exports.agent = (request, response) => {
const app = new DialogflowApp({ request, response });


Lastly, use the app.__() method to load the right response, and optionally provide a context (if you do have variables in your response):

const actionMap = new Map();
actionMap.set('', (app) => {
app.tell(app.__('MSG_001', { name: 'Wassim' }));

You an read more about this library here at


Congratulations, you are now ready to publish (or republish) your localized Action. But before, there is a last step where you need to provide a localized information of the Action that will be used in the Application Directory for the selected languages. This step takes only few minutes.

From the Google Assistant console, go to overview then App information, and click on the “Add language(s)” button:

Then select one or more languages. Make sure you select the same languages that you used during the design phase in DialogFlow:

Then, for each language, you will need to fill in the required inputs:

  • Assistant app name and pronunciation.
  • Assistant app introduction.
  • Assistant app voice.
  • Short and full description.
  • Sample invocations.


You are now ready to test your Action in the selected languages and locales. You can use the “Language” drop down list from the simulator:

In case you encounter the following error message: “You app must have at least one action for locale xx”:

This means that you MUST provide a locale for the selected language. For instance, that would be the case for European French. We will add a French locale for France:

You now have a specific version for users who speak French (from France). If you like, you can update the information for this specific locale—this is optional for our case:

The blue “LOCALIZED” label means that you have an active locale for a specific language:


Congratulations! You now have a localized Action that will provide a customized experience for all your users.

Follow me on Twitter @manekinekko to learn more about the Assistant and the web platform.