How to define a canonical URL in SPSEOHeaderTagsArticleView and/or SPSEOHeaderTags

Johan van den H
Kilo Sage

A large number of our public knowledge articles are not being indexed by Google Search.
This was shown in the Google Search Console which we recently configured for our portal.

 

The main reason for not indexeing the knowledge articles is "Duplicate without user-selected canonical".
We have not set a Canonical URL for our instance so this might help in getting more of our public knowledge articles to get indexed and thereby findable on Google Search.

 

The ServiceNow documentation (Configure custom SEO tags for canonical URLs and localized knowledge articles) tells us to change the SPSEOHeaderTagsArticleView script it does not clearly tell what we should change to define the Canonical URL.

We also found that there is a option to set to determine if page should use a SEO script, but this seems not specifically for knowledge articles (see ServiceNow documentation: Enable SEO for localized versions of a portal page).
The documentation refers to the SPSEOHeaderTags script.

Can someone help us out what we should change and if the SPSEOHeaderTagsArticleView script is the only thing we need to change?

5 REPLIES 5

Johan van den H
Kilo Sage

The canonical URL that is OOTB defined for knowledge articles is a self-referencing Canonical URL, which means that for our instance it can be either support.xyz.nl (our Custom URL) or xyz.service-now.com.

As this is not the best setting for getting our public knowledge articles findable on Google Search (or so I am told) we want to rewrite the self-referencing Canonical URL to match our Custom URL.

This has been achieved by changing this Script Include: SPSEOHeaderTagsArticleView (which overrides the out-of-the-box implementation of SPSEOHeaderTagsArticleViewSNC functions).

var SPSEOHeaderTagsArticleView = Class.create();
SPSEOHeaderTagsArticleView.prototype = Object.extendsObject(sn_km_portal.SPSEOHeaderTagsArticleViewSNC, {
    type: 'SPSEOHeaderTagsArticleView',
    _getPreferredHost: function() {
        // In our instances this already returns: 
        // DEV https://devsupport.xyz.nl/ 
        // TST https://tstsupport.xyz.nl/ 
        // ACC https://accsupport.xyz.nl/ 
        // PRD https://support.xyz.nl/ 
        return gs.getProperty('glide.servlet.uri').replace(/\/$/, '');
    },
    _swapHost: function(url) {
        if (!url) return url;
        var preferredHost = this._getPreferredHost();
        if (!preferredHost) return url;
		// optional short-circuit
		if (url.indexOf(preferredHost) === 0) return url;
        return url.replace(/^https?:\/\/[^\/]+/i, preferredHost);
    },
    generateCanonicalURL: function() {
        var url = sn_km_portal.SPSEOHeaderTagsArticleViewSNC.prototype.generateCanonicalURL.call(this);
        return this._swapHost(url);
    },
    generateHrefLangArray: function() {
        var arr = sn_km_portal.SPSEOHeaderTagsArticleViewSNC.prototype.generateHrefLangArray.call(this) || [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] && arr[i].href)
                arr[i].href = this._swapHost(arr[i].href);
        }
        return arr;
    }
});