- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
12-17-2023 10:53 AM - edited 04-15-2024 02:52 AM
Service Portal is intended to give a great user experience to our employees or customers, allowing them to access their services on a quick and easy way.
But, what if we want to go one step forward and give them the best possible experience, we can align the portal with their corporative branding. In this way, the employees from different sub-companies, or the customers from different accounts could enjoy a better experience when accessing the Service Portal.
How we can accomplish MutiBranding Portal?
The idea is to create new StyleSheets per company/account we want to personalize the exprience for. Then, when accessing the Portal we check the logged in user company/account and load the StyleSheet if there is one for that particular company/account, and we keep the default styles if not.
SOLUTION
In the next example, we are personalising the experience for customers, so we are using the Account Number in order to distinguish the different StyleSheets, but it could be done also for employees/sub-companies.
- Create StyleSheet with the Account Number as Name and set the personalised styles there. Do not attach the StyleSheet to the Portal theme, as it will be done dynamically based on the Account the logged in user is member of.
New StyleSheet:
- Name: ACCT0000001 (Account Number)
- CSS:
body { /* Hack for prevent default styles to appear before the personalised ones */ display: block; } h2 a, a { color: #ffa31a !important; } .navbar { background-color: #043559; border-bottom: .4rem solid #ffa31a !important; } .navbar .navbar-brand-logo { background-image: url('/Acme_logo_yellow.png'); background-position: 10px 10px; background-repeat: no-repeat; background-size: 195px 50px; width:200px; height: 50px; margin: 0; } .navbar .navbar-brand-logo img { display: none !important; } .navbar a { color: #ffa31a !important; text-transform: uppercase !important; font-weight: bolder; } body main.body .cbe98a8d2cb20020000f8d856634c9c63 { background: rgb(2,0,36) !important; background: linear-gradient(180deg, rgba(2, 29, 49,1) 0%, rgba(4,53,89,1) 35%, rgba(0,212,255,1) 100%) !important; } main.body .homepage-quicklinks { background-color: #eeeeee; } main.body .homepage-quicklinks a h2 { color: #ffa31a; } .btn-primary { color: #043559; background-color: #00d4ff; border-color: #04a3c3; } .v94c300c7e777320075c2a117c2f6a9e7 .spw-announcements-root .details div.title div, .v94c300c7e777320075c2a117c2f6a9e7 .spw-announcements-root .details div.title a { color: #ffa31a; } .v1e699082d7001200a9addd173e24d4e3 .bs-callout-success { background-color: #ffe0b3 !important; border-color: #ffa31a !important; }
Note: it is a quick example in which we configure some basic colours for links, sections' backgrounds, and we change the corporative logo selecting one we previously uploaded to System Images.
- Create a client callable Script Include in which we define the function returning the Account number for the current user.
New Script Include:
- Name: multiBrandingSP
- API Name: global.multiBrandingSP
- Client Callable: true
- Application: Global
- Accessible from: All application scopes
- Active: true
- Script:
var multiBrandingSP = Class.create(); multiBrandingSP.prototype = Object.extendsObject(AbstractAjaxProcessor, { getStyleSheetFromAccount: function() { try { var css_id = ''; var user_account_number = ''; // Get user account number var userAccountGR = new GlideRecord('customer_account'); if (userAccountGR.get(gs.getUser().getCompanyID())) user_account_number = userAccountGR.getValue('number'); // Get StyleSheet by name using the account number var styleSheetGR = new GlideRecord('sp_css'); if (styleSheetGR.get('name', user_account_number)) css_id = styleSheetGR.getUniqueValue(); // Return StyleSheet sys_id return css_id; } catch (e) { gs.error('Error - ScriptInclude (multiBrandingSP): ' + e); } }, type: 'multiBrandingSP' });
- Create a UI Script to load the StyleSheet if there is one for the user account.
New UI Script:
- API name: serviceportal_overlay
- UI Type: All
- Application: Global
- Active: true
- Script:
loadMultiBrandingStyles(); function loadMultiBrandingStyles() { // Call the Script Include in order to get the StyleSheet sys_id var ga = new GlideAjax('global.multiBrandingSP'); ga.addParam('sysparm_name', 'getStyleSheetFromAccount'); ga.getXML(uploadStyleSheet); } function uploadStyleSheet(response) { var answer = response.responseXML.documentElement.getAttribute("answer"); // If any sys_id is returned, load the associated StyleSheet if (answer) jQuery('head').append('<link rel="stylesheet" type="text/css" href="/' + answer + '.spcssdbx?">'); // Else allows the default styles to be displayed. else jQuery('body').attr('style', 'display:block'); }
- Attach the previous UI Script to the Service Portal theme
- Customise default StyleSheet for the theme in order to do not display content. It prevents the default styles to appear for an instant before we load the personalised styles.
If this is not needed, you can avoid the "else" code on the previous UI Script and also this 5th step.
Customise default StyleSheet:- Name: sp-theme-la-jolla.css
- CSS (add the following line):
body {display:none;}
RESULT
Default Service Portal style when there is no StyleSheet defined for the logged in user account:
Personalised Service Portal style when there is a StyleSheet defined for the logged in user account. In this example we changed the corporative logo, colours and backgrounds:
ALTERNATIVE SOLUTION
Same solution could be achieved by different ways. Another one is to create a custom widget and embed it on the Portal Header, loading the desired StyleSheet if there is one associated with the user company/account.
Widget Body HTML Template:
<link href="/{{::data.css_id}}.spcssdbx?" rel="stylesheet" type="text/css" ng-if="data.css_id!=''" />
Widget Server Script:
(function() {
try {
data.css_id = '';
var user_account_number = '';
var userAccountGR = new GlideRecord('customer_account');
if (userAccountGR.get(gs.getUser().getCompanyID()))
user_account_number = userAccountGR.getValue('number');
var styleSheetGR = new GlideRecord('sp_css');
if (styleSheetGR.get('name', user_account_number))
data.css_id = styleSheetGR.getUniqueValue();
} catch (e) {
gs.error('Error - Widget (SN - Load Customer StyleSheet): ' + e);
}
})();
Header Body HTML Template:
<sp-widget widget="data.loadCustomerStyle"></sp-widget>
SOLUTION CONSIDERATIONS
The proposed solution has no contras or secondary effects as it does not require any update on ootb records, so there will not be any conflict raised when upgrading the platform. On the other hand, the alternative solution is updating the Portal Header and could require some effort on maintenance/upgrade, that is why it is not the best option.
Hope it helps! 😉
Kind regards,
Luis Estéfano
- 5,038 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello @Luis Estefano,
We have a similar requirement, we need to display different background image in the Employee Center(esc portal) based on the logged in user company. If the company field is empty, we need to display the default image which has been set in the container using the 'Instance in Page Editor'. We have tried the above given solution, but the image is not getting displayed.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @sjadhav1,
the previous configuration has been designed for SP portal, not ESC. For ESC you need to do some adjustments on the CSS and adapt the styles to the ESC Theme.
For example, we change the background gradient with the following lines:
body main.body .cbe98a8d2cb20020000f8d856634c9c63 {
background: rgb(2,0,36) !important;
background: linear-gradient(180deg, rgba(2, 29, 49,1) 0%, rgba(4,53,89,1) 35%, rgba(0,212,255,1) 100%) !important;
}
In the ESC Portal, the HTML elements are not the same and you need to adapt it. Something like this could do the trick:
body > div > section.page {
background: rgb(2,0,36) !important;
background: linear-gradient(180deg, rgba(2, 29, 49,1) 0%, rgba(4,53,89,1) 35%, rgba(0,212,255,1) 100%) !important;
}
The result on ESC would look like:
Please, let me know if that helps! Thank you!
Kind regards,
Luis Estéfano
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello Luis,
Can we do multi-branding on Mobile agent?
Thanks!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello @Luis Estefano ,
Could you please explain this step in more detail -
Attach the previous UI Script to the Service Portal theme
Thank you!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Smita9,
For mobile theming, you have legacy and the Next Experience theming, depending on your current release and configuration. However, mobile theming is configured differently from Service Portals, so this approach doesn't apply to the Mobile App.
ServiceNow Documentation
I hope this clarifies things, and apologies for the delayed response!
Kind regards,
Luis Estéfano
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello @alex2410,
Sure, let me provide more details on those steps:
- Go to the Portal Record [sp_portal]
"Service Portal -> Portals" from the main menu - Access the associated Theme [sp_theme]
"Theme" field on Portal record - Navigate to the related lists and create a new JS Include [m2m_sp_theme_js_include]
"JS Include" related list is at the bottom of the Theme form by default - Add the UI Script to the JS Include, ensuring it is attached to the Portal Theme.
I hope this helps you get it working, do not hesitate to ask if it is not clear enough!
Kind regards,
Luis Estéfano
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@Luis Estefano I am trying to apply same for portal-polaris-common-theme? any tips on how to go forward?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hello @RichardK781 ,
The solution is the same; however, you'll need to adjust the CSS styles to match the specific theme you want to customize for each account. Anyone with basic CSS knowledge should be able to handle this, but feel free to reach out if you need assistance. I'll be happy to provide guidance or insights.
Kind regards,
Luis Estéfano
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
If you're dealing with multiple portals and unique branding for each, a solid approach is to use custom themes alongside appropriate widgets and CSS adjustments. I’ve found that setting up brand-specific UI scripts helps maintain consistency across different portals without breaking existing functionality. It might be useful to check if someone has shared additional insights on the kickstarter page, as these discussions often bring out clever workarounds.