The CreatorCon Call for Content is officially open! Get started here.

Markus Kraus
Kilo Sage

Business Case: All ServiceNow Users should be presented with the Login Page in their native language

Why this article: All implementations i have found so far work with client side scripting and page reloads. This is a really bad user experience.

Why use the method shown in this article: We simply set the guest-User language server side and do this by parsing the 'Accept-Language' header which the browser sends. This is done all known and relevant browsers (Source: mdn).

How this method works: There are two entry points to get to the login page: 
A) Access via "internal" link (e.g. /incident_list.do)
B) Access via portal link (e.g. /sp?id=approvals)

Setting the language for A) is easy, it only requires a small modification to the SPEntryPage Script Include (and if not already in use, requires a certain System Property to be set). Modifying this Script Include is supported and recommended by ServiceNow (in short: Best Practice).

Setting the language for B) is a little bit more difficult and might need more modifications, as every portal theme in-use has to be modified. In detail, we are going to replace the header used by the theme and will execute the "set-language" function *before* any other code is executed.

 

Scoped App which includes all necessary scripts and has a built-in check for all required settings to implement this feature:

https://github.com/kr4uzi/ServiceNow-Automatic-Login-Language.git

 

A) (Internal) modification:
1.) Make sure that the sys_properties glide.entry.page.script is set to new SPEntryPage().getLoginURL();
2.) Modify the SPEntryPage Script Include like this:

 

...
	getLoginURL: function() {
		var user = gs.getUser();
		if (user.getName() == 'guest') {
			var acceptLanguage = GlideTransaction.get().getRequest().getHeader("Accept-Language");
			if (acceptLanguage) {
				var isoLanguage = acceptLanguage.substring(0, 2);
				var choiceGr = new GlideRecord('sys_choice');
				choiceGr.addEncodedQuery('name=sys_user^element=preferred_language');
				choiceGr.addQuery('language', isoLanguage);
				choiceGr.setLimit(1);
				choiceGr.query();
				if (choiceGr.hasNext()) {
					user.setPreference("user.language", isoLanguage);
					user.savePreferences();
				}
			}
		}
...

 

 

B) (External) modification:
1.) Identify the used theme:
a) Navigate to the Portal Record (sp_portal.list)
b) Open the Theme Record
c) Open the Header Record and save the Sys Id of it

2.) Create a new Header Widget (sp_header_footer.do)
a) Switch the the Global Scope, or any global scoped App
b) Save the record with the following values (note: now you need the Sys Id of the OOTB Header Record):
Body HTML Template: 

 

<sp-widget widget="data.widget" />

 

Server script: 

 

(function() {
	var user = gs.getUser();
	if (user.getName() == 'guest') {
		var acceptLanguage = GlideTransaction.get().getRequest().getHeader("Accept-Language");
		if (acceptLanguage) {
			var isoLanguage = acceptLanguage.substring(0, 2);
			var choiceGr = new GlideRecord('sys_choice');
			choiceGr.addQuery('name', 'sys_user');
			choiceGr.addQuery('element', 'preferred_language');
			choiceGr.addQuery('language', isoLanguage);
			choiceGr.setLimit(1);
			choiceGr.query();
			if (choiceGr.hasNext()) {
				user.setPreference("user.language", isoLanguage);
				user.savePreferences();
			}
		}
	}
	
	data.widget = $sp.getWidget('<Sys ID of the OOTB Header Widget>', options);
})();

 

 

3.) Modify the Theme Record from Step 1)
a) Replace the Header with the newly created Header Widget in Step 2)
b) Save the Record

4.) Done

Version history
Last update:
‎11-11-2023 03:02 PM
Updated by:
Contributors