Shahed Shah1
Tera Guru

On the web, the URL of a page plays a huge part in your user experience and the success of navigation. If your ServiceNow URL schema is constructed incorrectly you could end up sending your visitors to the wrong page, or worse: an error message. Last week I was helping a customer who was creating an Email Notification that would link back to a Service Catalog form within the usual Instance UI (the frameset). Based on the building blocks for URL creation, we were able to work out how the customer could link within the frameset.

The customer was having an issue where the URL would fail and present to the users a "Not Authorized" message. When looking into this with the customer, the issue came down to how the uri parameter was being used and how the value was being encoded.

Let's start with:

https:// <instancename>.service-now.com/nav_to.do?uri=

Remember that the nav_to.do page in the above URL will resolve to navpage.do, which is the frameset and ensures the requested page in the uri parameter is loaded into the main frame.

To demonstrate this, let's look an example you will already be familiar with:

https://<instancename>.service-now.com/nav_to.do?uri=incident_list.do%3Factive%3Dtrue

When clicking on the link you will be taken to the Instance and, in the main frame, be shown the Incident list.

The following URL would also achieve the same result:

https://<instancename>.service-now.com/nav_to.do?uri=incident_list.do?active=true

In many cases, the browser can be forgiving. Now, I say forgiving because a URL can get weird when you have a more complicated "sub" link. This is where I commonly see issues arise.

Key points in URL navigation:

  1. Everything before the first question mark (?) is familiar to everyone.
  2. After the question mark is a query string.
  3. Query strings are separated with the ampersand (&).
  4. The uri parameter is, essentially, expecting an encoded URL.

Now, let's demonstrate what was going wrong with the customer using an base system demo. Let's pick the good ol' Create Incident record producer and try opening it in a new tab. This will let us grab the respective URL.

To obtain the URL of an incident record:

  • Navigate to Service Catalog > Record Producer.

  • Go into the Create Incident record.

  • Click on Try It.
  • Right-click on a blank area of the page and select This Frame > Open Frame in New Tab (this is for Firefox but you can get a plugin for Chrome to do similar. I use this one).

This is what I got from a Eureka demo:

https://<instancename>.service-now.com/com.glideapp.servicecatalog_cat_item_view.do?v=1&sysparm_id=3f1dd0320a0a0b99000a53f7604a2ef9&sysparm_link_parent

=e15706fc0a0a0aa7007fc21e1ab70c2f&sysparm_catalog=e0d08b13c3330100c8b837659bba8fb4

&sysparm_catalog_view=catalog_default

You will not be able to take the com.glideapp.servicecatalog_cat_item_view.do page and parameters, then place it in uri parameters. Trying to do so will result in a "Not Authorized" message.

Screen Shot 2015-05-07 at 11.09.51.JPG

(Pretty, isn't it?)

This is because all the ampersands (&) are being interpreted at the level of nav_to.do, when it should be interpreted at the level of the com.glideapp.servicecatalog_cat_item_view.do page. So that means we need to encode that URL into the uri parameter.

A way around this is to use the URL Encoder built into the DuckDuckGo search engine. To get the URL, just enter "url encode [url]" into the search box (of course change [url] to the URL of interest).

So:

com.glideapp.servicecatalog_cat_item_view.do?v=1&sysparm_id=3f1dd0320a0a0b99000a53f7604a2ef9

&sysparm_link_parent=e15706fc0a0a0aa7007fc21e1ab70c2f&sysparm_catalog

=e0d08b13c3330100c8b837659bba8fb4&sysparm_catalog_view=catalog_default

Would become:

com.glideapp.servicecatalog_cat_item_view.do%3Fv%3D1%26sysparm_id%3D3f1dd0320a0a0b99000a53f7604a2ef9

%26sysparm_link_parent%3De15706fc0a0a0aa7007fc21e1ab70c2f%26sysparm_catalog

%3De0d08b13c3330100c8b837659bba8fb4%26sysparm_catalog_view%3Dcatalog_default

The next step would be to add this to: https://<instancename>.service-now.com/nav_to.do?uri=

Now when I built the whole URL, I would get:

https:// <instancename>.service-now.com/nav_to.do?uri=com.glideapp.servicecatalog_cat_item_view.do%3Fv%3D1

%26sysparm_id%3D3f1dd0320a0a0b99000a53f7604a2ef9%26sysparm_link_parent

%3De15706fc0a0a0aa7007fc21e1ab70c2f%26sysparm_catalog%3De0d08b13c3330100c8b837659bba8fb4

%26sysparm_catalog_view%3Dcatalog_default

Trying it out now will show the Create Incident Record Producer within the Instance frameset.

Screen Shot 2015-05-07 at 11.16.12.JPG

(Yay! )

This concept will also apply if you were to create a Content Page within your CMS portal that would dynamically load the content into an iFrame. Whatever you decide to call the parameter to do the deed, don't forget to encode the URL.

Another reference to use for encoding the URL is available from here: HTML URL Encoding Reference. This page hosts a table for you to look up the character of interest and will provide the encoding required.

Typical characters that are up for encoding are listed in this table:

CharacterEncoding from UTF-8
?%3F
&%26
=%3D
@%40
%%25
13 Comments
brnunn
Tera Contributor

Super useful article (though hard to find).



I could not figure out why the nav_to.do?uri = didn't work with record producers but the answer is so obvious in retrospect ><



Thanks!


Shahed Shah1
Tera Guru

Thanks Rafael. I'm glad it helped. I will add more tags to this in the hope that it will be easier for others to find.


joshuac
Kilo Contributor

Thank you for the informative post! This works great for deep linking through the normal UI, but I was hoping it would cover deep linking to CMS pages. We are having trouble navigating to a page inside the ServiceNow Content Management (CMS).   Assuming the site prefix is 'mysite', our URL to a service catalog item is:


https://<instancename>.service-now.com/nav_to.do?uri=mysite%2Fcom.glideapp.servicecatalog_cat_item_view.do%3Fv%3D1%26sysparm_id%3D6190bc0e4f7bce00010601b28110c7ba%26sysparm_link_parent%3D8775a32c4fac9200c360b3318110c7af%26sysparm_catalog%3De0d08b13c3330100c8b837659bba8fb4%26sysparm_catalog_view%3Dcatalog_default



This will route to the correct authentication page within the servicenow CMS, but after authentication,   redirects to the service catalog page in the normal UI (without /mysite).



What parameter is missing? What format is incorrect? Or How do we deep link to a catalog item inside a ServiceNow CMS frame?



thank you!


-Josh


Shahed Shah1
Tera Guru

Hi Joshua



CMS and the Service Catalog is a bit of a different beast. Usually, the CMS will have Pages that would contain static iframes which would then link to the Service Catalog, so that navigating to any Catalog Item/Record Producer would happen within that iframe.



As one idea, you could create a generate CMS page with a dynamic block, which then loads up the desired Catalog Item/Record Producer based on the URL parameters. But of course, the deep link would have to differ for that to work. There's of course many ways of achieve this and would take a bit of tinkering to get right.



Hope that helps


Shahid


joshuac
Kilo Contributor

Hi Shahid,



I have used the dynamic block method, and it seems to work!



Thank you for the help!



-Josh


Chad Wilhelm1
Tera Expert

Hello Shahid,



How would you populate Service Catalog variables via this methods of populating via URL?     I have this url which opens a catalog item but I cannot figure out to pass something to the variable.



nav_to.douri=com.glideapp.servicecatalog_cat_item_view.dosys_id=-1%26sysparm_id=93d32242dbcf5a401c76d9fdbf961921%26sysparm_query=description=Hello



Thanks for your assistance.


Chad


Shahed Shah1
Tera Guru

Hey Chad,



Unfortunately, there is no mechanism currently builtin that would consume URL parameters and update the variable values.



I did find a nice answer documented here: CMS pass catalog variables via custom URL . Look at Stephen's reply where he suggested that you put in the desired URL parameters and then set the Default Value using javascript, such as:


javascript:RP.getParameterValue('sysparm_short_description');



Just to throw caution, you would not make to put too many parameters as there are character limits for large URLs. The limits do vary from browser to browser. See What is the maximum length of a URL in different browsers? - Stack Overflow for more info.



Shahid


Laurie Marlowe1
Kilo Sage

Hi Shahid,



I am trying to add a link to a Knowledge Article from a form.   I want it to open in a new window.   I followed your instructions for "This Frame->Open Frame in New Tab".   I copied the URL to my URL field:


Capture.JPG


When I click on the link it does exactly what I want it to do.   Now I want to be able to click the link from list view, but it doesn't work.   It just takes me to another form in the application.   The app is On-call Scheduling.



Capture.JPG


Any ideas?   It's the same link!



Thank you,



Laurie


Shahed Shah1
Tera Guru

Hi Laurie



I just tried to set up something similar on my Geneva demo (URL field on Incident table) and it works for me. One thing that looks suspicious is the URL format in your initial screenshot:


https://instancename.service-now.com/kb_view.do%3Fsys_kb_id%3De97ee81eff6002009b20ffffffffffe0



Shouldn't it be like this?:


https://instancename.service-now.com/kb_view.do?sys_kb_id=e97ee81eff6002009b20ffffffffffe0



In this case when you click on the URL in the List View, it will open up into a new tab, so the full URL rather than an encoded one is needed.



Let me know if that works for you.



Regards


Shahid


Laurie Marlowe1
Kilo Sage

Hi Shahid,



You are correct about the URL!   You are a URL genius!



Thank you so much,



Laurie