Adding CSS and JavaScript files to SharePoint 2013 masterpage

cover image

There are different ways to add CSS and JavaScript files to SharePoint masterpage. Let's review them and clarify which is the most useful one.

Here is a shortcut to the final version:

<!--SPM:<SharePoint:CssRegistration runat="server" ID="CssRegistration1" Name="&#60;% $SPUrl:~sitecollection/Style Library/style.css %&#62;" After="corev15.css"/>-->

<!--SPM:<SharePoint:ScriptLink runat="server" ID="ScriptLink1" Language="javascript" Name="~sitecollection/Style Library/script.js"/>-->

CSS

There are two solutions for CSS. SharePoint:CssRegistration tag and link tag. Using the default link tag is a good solution, but does not offer as much flexibility as the SharePoint:CssRegistration tag does. We will use server SharePoint:CssRegistration tag to get access to utility attributes it can offer;

Let's review the structure of the SharePoint:CssRegistration declaration:

<!--SPM:<SharePoint:CssRegistration runat="server" ID="CssRegistration1" Name="&#60;% $SPUrl:~sitecollection/Style Library/style.css %&#62;" After="corev15.css"/>-->

ID

ID="CssRegistration1"

As a server tag, CSSRegistration needs to have an unique ID. Don't forget to change it, when using multiple CSSRegistration tags.

After

After="corev15.css"

After property allows us not to worry if our style file is loaded after default styles, no matter where it is declared on a page.

ConditionalExpression

ConditionalExpression="lt IE 9"

Another attribute is ConditionalExpression that will generate conditional comments for you to target specific IE versions (not used in this particular example);

Name

Name="/Style Library/style.css"

And the most interesting here, the Name attribute. It is used to get the URL of a CSS file. Normally you would use it to refer to a file in a relative way like /Style Library/style.css, but in cases when your collection in not in the root this would cause problems, as a page will look for resources in the wrong directory. You can't use ~sitecollection token directly inside Name attribute, but this can be fixed with $SPUrl.

$SPUrl

<$SPUrl:~sitecollection/Style Library/style.css>

You can use $SPUrl inside the Name attribute because we use a server-side tag. And you can use a ~sitecollection token inside it to refer to a site collection directory.

The only thing to mention here that there is a little trick to insert an $SPUrl into Name attribute at CSSRegistration tag. You need to encode opening and closing brackets, so the server won't interpret closing bracket as an end of CSSRegistration tag.

&#60;% $SPUrl:~sitecollection/Style Library/style.css %&#62;

JavaScript

There are two solutions for JavaScript files, too.

The first one is script tag. It has several useful attributes:

src

Here comes the URL to your external script file.

async

If set to async the script will be executed asynchronously.

defer

If set to defer the script will be executed when the page has finished parsing.

The second one is SharePoint:ScriptLink. Things to know about it:

  • Ensures that the script is loaded only once;
  • Ensures that other dependencies have been loaded first;
  • By default looks to LAYOUTS/%LanguageID% folder;
  • Can be used with ~site and ~sitecollection tokens.

Let's review the structure of the SharePoint:ScriptLink declaration:

<!--SPM:<SharePoint:ScriptLink runat="server" ID="ScriptLink1" Language="javascript" Name="~sitecollection/Style Library/script.js"/>-->

ID

ID="ScriptLink1"

Required. Don't forget to change if you use several tags.

Language

Language="javascript"

Required.

Name

Name="~sitecollection/Style Library/script.js"

Required. Contains the script name. By default, it looks for the script in the LAYOUTS folder. You can use ~sitecollection and ~site tokens to load the script from your Style Library folder, for example.

OnDemand

OnDemand="true"

If set to true, renders RegisterSod("~sitecollection/style library/script.js", "\u002fstyle\u002520library\u002fscript.js"); to use SharePoint "Script On Demand" functionality.

LoadAfterUI

LoadAfterUI="true"

This one is supposed to put the script reference just before the html closing tag, so your script will execute after the rest of the page has been already loaded.
But I couldn't achieve this at my SharePoint 2013 Enterprise environment. Maybe it works with Office 365 or with some other version, or just doesn't work at all.

Localizable

Localizable="true"

This will make the control to look for your script in language specific folder (e.g. _layouts/1033/script.js).

Conclusion

So here is the final version:

<!--SPM:<SharePoint:CssRegistration runat="server" ID="CssRegistration1" Name="&#60;% $SPUrl:~sitecollection/Style Library/style.css %&#62;" After="corev15.css"/>-->

<!--SPM:<SharePoint:ScriptLink runat="server" ID="ScriptLink1" Language="javascript" Name="~sitecollection/Style Library/script.js"/>-->

Using this will ensure your resources are requested from the same location no matter how your site structure changes, and it allow you to use some useful features like automatically generated conditional comments or "Script On Demand" functionality.