Understanding the ScriptHelper API in Kentico


Unless you’re sticking to your web design skills from 1998, you mostly are incorporating some sort of front-end framework into your applications. Whether it’s JavaScript libraries, templating engines, or just some sweet code to add trails to your mouse movements, external scripts often power the captivating experience users have come to expect. In this article, I’ll give you some important information on the ScriptHelper class in Kentico to help build out your controls. 

Because Kentico is a .NET application, it leverages a lot of the framework for functionality. From UI Pages to user controls, nearly every class within the platform is derived from a .NET component. In addition to objects, many of the helper classes in Kentico also extend these standard APIs to provide a more dynamic and integrated experience.

Because so many applications require a plethora of scripts to function, registering JavaScript frameworks and other components properly is a critical step in the development process. To help you with this task, Kentico has the ScriptHelper API which simplifies your code and lets you leverage a common interface for loading your external libraries. This API provides you with several functions to help you bring in core Kentico scripts, as well as register your own files.

A few important notes

Before you go using the ScriptHelper throughout out your project, you need to understand a few important aspects of the API. Knowing these tips will save you a lot of time in the future, and help you write better Kentico code.

1.       The ScriptHelper API will include scripts either in the form or in the head tag. It’s best practice to load all scripts at the closing body tag, so be aware of how/when the API will load your scripts.

2.       If you use the ScriptHelper to load Kentico’s built-in jQuery, you will need to us the $cmsj alias to access it within in your code. You can found more about this here. (https://docs.kentico.com/k10/custom-development/best-practices-for-customization#Bestpracticesforcustomization-UsingjQuery)

3.       By using the ScriptHelper API to load in the built-in jQuery, Boostrap, or other out-of-the-box libraries, you run the risk of having broken code during upgrades. Because Kentico may change the version of jQuery we use, you will need to thoroughly test your code to make sure it works with the new version. You may need to explicitly load previous versions to keep your code running smoothly.

4.       Loading scripts individually with the ScriptHelper API is considered inefficient because it will load all the files separately. Ideally, you will want to combine your JS loading calls into as few as possible, or leverage Grunt/Gulp to ensure your site performs optimally.

5.       Using the ScriptHelper API isn’t a fit for every scenario. You will usually only want to us it when you won’t have access to the whole HTML document, such as when working with form controls and other backend components.

With those notes out of the way, let’s get to a scenario where you may want to use the API.

Creating a web part

I created a simple web part to show the functionality (and a design of Da Vinci quality!). I placed the web part on a blank page within my site, to remove any existing JS calls that the base master page may load. From there, I added several API calls to show the various functions available.



This call will load the built-in BootStrap scripts to your page. This allows you to leverage the standard BootStrap files as part of your layout to ensure a consistent look and fee.

API Call




This API call will register the built-in jQuery library on your page. This allows you to leverage the jQuery version that ships with Kentico without any additional code.

API Call




Over the years, Kentico has included many 3rd party libraries to help both with the administration site, as well as to provide functionality to developers. For images, the RegisterLazyLoad function allows you to load built-in JS to load graphics more effectively.

API Call

ScriptHelper.RegisterImageLazyLoad(this.Page, "lazyloadimages", "lazyload"); strHTML += "<div class='lazyloadimages'><img src='/Kentico10WebApp/DancingGoat/media/graphics/logos/dancing-goat.png' class='lazyload'/></div>";

Lazy Load


Another handy out-of-the-box library is the Spell Checker. The RegisterSpellChecker function loads the built-in spell checker JS library to help you ensure your inputs are valid.

API Call




Often, you need to load your own JS files into your site. The RegisterScriptFile function allows you to specify a code file to load.

API Call

ScriptHelper.RegisterScriptFile(this.Page, "https://code.jquery.com/jquery-1.12.0.min.js");



This function allows you to register a startup script to your page/control. Because many libraries are dependent on when /where they sure loading the lifecycle, using this option can allow you to load your scripts before the closing tag. Additionally, this function allows you to load a script blog, instead of an actual file.

API Call

strJS += "console.log('Startup script loaded');"; ScriptHelper.RegisterStartupScript(this, typeof(string), "StartUpScript", strJS, true);


Moving Forward

The ScriptHelper API contains many more functions to help you develop your projects. Because it’s based on the ClientScriptManager and other .NET libraries, you should be able to get running with it in no time. Be sure to check out the full list of options to get the most of the platform. Be sure you fuilly understand how the API works before you implement, to ensure you get the exact results and compatibility within you code. Good luck!

Here is the full webpart source code, if you were curious:

using CMS.Base.Web.UI; using CMS.PortalEngine.Web.UI; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace Custom { public partial class ScriptHelperDemo : CMSAbstractWebPart { #region Member Variables #endregion #region "Properties" #endregion /// <summary> /// Content loaded event handler. /// </summary> public override void OnContentLoaded() { base.OnContentLoaded(); SetupControl(); } /// <summary> /// Initializes the control properties. /// </summary> protected void SetupControl() { if (StopProcessing) { // Do nothing } else { } } /// <summary> /// Reload data. /// </summary> public override void ReloadData() { base.ReloadData(); SetupControl(); } protected void btnSubmit_Click(object sender, EventArgs e) { lblResults.Text = ""; try { string strJS = ""; string strHTML = ""; if (cbBootstrap.Checked) { ScriptHelper.RegisterBootstrapScripts(this.Page); } if (cbJQuery.Checked) { ScriptHelper.RegisterJQuery(this.Page); } if (cbLazyLoad.Checked) { ScriptHelper.RegisterImageLazyLoad(this.Page, "lazyloadimages", "lazyload"); strHTML += "<div class='lazyloadimages'><img src='/Kentico10WebApp/DancingGoat/media/graphics/logos/dancing-goat.png' class='lazyload'/></div>"; } if(cbSpellchecker.Checked) { ScriptHelper.RegisterSpellChecker(this.Page); } if (cbStartupScript.Checked) { strJS += "console.log('Startup script loaded');"; } if (cbScript.Checked) { ScriptHelper.RegisterScriptFile(this.Page, "https://code.jquery.com/jquery-1.12.0.min.js"); } if (strJS != "") { ScriptHelper.RegisterStartupScript(this, typeof(string), "StartUpScript", strJS, true); } if (strHTML != "") { lblResults.Text = strHTML; } } catch(Exception ex) { lblResults.Text = ex.Message; } } } }

Share this article on   LinkedIn

Bryan Soltis

Hello. I am a Technical Evangelist here at Kentico and will be helping the technical community by providing guidance and best practices for all areas of the product. I might also do some karaoke. We'll see how the night goes...