Localization in Service Portal


As most companies experience globalization in some capacity, it’s important that they localize their portals to accommodate users from different areas around the world. In this article, I will go through the different components involved with localizing your Service Portal.

Before we begin, make sure to activate the internationalization (i18n) plugin and the required language pack plugins that will be used by your organization. Also, there is an OOB widget called “Language Switch.” Simply include this widget somewhere in the portal to enable users to update their language preferences.

The two primary tables in ServiceNow responsible for storing translations for Service Portal are:

  1. Message
  2. Translated Text

We will also cover some of the other tables and plugins that can potentially impact translating a portal.

Message table (sys_ui_message)

The UI message table contains translations using key/value pairs. The key is the string in the base language and the value is the localized version of that string. The main fields on this table are:

  • Key: unique identifier of this message (usually the English version of the string).
  • Language: language the message is translated into.
  • Message: translated text that users see.

In Service Portal, the primary area you would see UI Messages used is inside widgets (in the HTML, Client Controller, and Server Script), but can also be commonly found in other areas with server-side scripts (e.g. Scripted Menu Items, Script Includes, etc.).


Use the ${} syntax in widgets to tag strings for translation

If translating a string stored in a variable, it is also possible to wrap a data binding {{}} with ${} to translate the contents of the variable.

However, I do not recommend using this approach. It is much better to do the translations server-side whenever possible.

Client Controller

Similar to HTML, you can also use ${} in the controller if it’s going to be displayed in the HTML

Note: In some cases, the translation might have quotes or double quotes in it. That could lead to JavaScript errors if you are using the ${} syntax in the client script. The safest way to fetch a translated message is to do it in the server script.

Another way, and perhaps better way to access translated strings in the controller is using the i18n service.

In order to use the i18n service, you must also declare the variable in the HTML using the <now-message> syntax

And then you can render the message in HTML using the {{}} syntax

Server Script

For all server-side translations, use the gs.getMessage() method

It is also possible to format certain template strings by passing in an array of strings as the second parameter:

This would return: “Welcome Nathan Firth – you have 5 active tickets.”


To demonstrate the various ways of doing translations using the sys_ui_message, here is a quick screen capture of the Widget Editor showing the string translated and used four different ways in the same widget. The string in all four cases is “Hello World”, and I’m translating it to say “Hello There”.

Click image to see full size

Translated Text table (sys_translated_text)

The Translated Text table stores translations for fields with the field type translated_text or translated_html.

The main fields for this table are:

  • Document: internal identifier of the record this translation applies to.
  • Field name: field this translated text appears in, for example, Close notes.
  • Language: language the text is translated into.
  • Table Name: table this translation applies to.
  • Value: translated text that the user sees.

Some common areas in Service Portal using Translated Text fields include:

  • Widget Instances (title, short_description)
  • Catalog Categories (title, description)
  • Menu Items (label)
  • Knowledge Categories (label)

Other translation tables

Although the Message and Translated Text are the primary tables used in Service Portal, there are also a few others worth noting:

  • Knowledge (kb_knowledge) if you’ve activated the “com.glideapp.knowledge.i18n2” plugin, you can also translate articles directly using the Knowledge tables.
  • Choice (sys_choice) table contains translated text for options that appear in choice lists.
  • Field Label (sys_documentation) table stores the text of table names along with the singular and plural labels for each field in the table.

Session at K19

Manually extracting, translating, and importing strings is time-consuming and error-prone. We will be leading a CreatorCon session at Knowledge19 in Las Vegas where we will be presenting on internationalization and making recommendations on to make this process less painful. Stay tuned for more information about that session.


We’re working on a brand new scoped application that will automate the extratction and importing of translations for Service Portal. If you are interested in seeing a demo or would be interested in this upcoming application, please don’t hesitate to reach out.


  1. Building such an app that would parse all your SP pages and let you know about un-internationalized strings, missing translations and unused keys.. that would come in handy.

  2. Is it possible have the parameters substitution on client side?
    on server side we can use this command:
    gs.getMessage(“Welcome {0} – you have {1} active tickets.”, [userName, numberOfTickets])

    there is a similar way to do the same thing on client side?
    ${“Welcome {0} – you have {1} active tickets.”);

    1. You can use the i18n service paired with the “<now-message>” syntax in your HTML, looking something like this:

      <now-message key="has added {0}" value="${JS,HTML:gs.getMessage('has added {0}')}"/>

Leave a Reply

Your email address will not be published. Required fields are marked *