Before SPFx, if you wanted to change how a column or a whole list view looked — colour-code a status, render a progress bar, format a number — you reached for JSLink and the Client-Side Rendering pipeline. CSR is a classic-mode technology, but it is still alive on countless classic lists and publishing pages, and understanding it explains a lot about how SharePoint thinks about rendering.
What CSR is
Client-Side Rendering (CSR) replaced the old server-side XSLT rendering of list views with a JavaScript pipeline that runs in the browser. The framework exposes a set of override points — for the view, the header, the body, individual rows, and each field in each form mode (View, Edit, New, Display). You register JavaScript that supplies replacement render logic for any of these points.
JSLink is simply the property that tells SharePoint which JavaScript file(s) to load for a given field, web part, or content type. Point a list view web part's JSLink at your script, and your overrides take effect.
The shape of an override
You build a template overrides object and hand it to SPClientTemplates.TemplateManager.RegisterTemplateOverrides. Here is a field override that colour-codes a Status column in the list view:
(function () {
// Define the override
var overrides = {
Templates: {
Fields: {
"ContractStatus": {
View: renderStatus // override the View render
}
}
}
};
function renderStatus(ctx) {
var status = ctx.CurrentItem.ContractStatus;
var color = {
"Draft": "#9e9e9e",
"In Review": "#f0ad4e",
"Approved": "#5cb85c",
"Archived": "#777"
}[status] || "#333";
return "<span style='padding:2px 8px;border-radius:4px;color:#fff;" +
"background:" + color + "'>" +
STSHtmlEncode(status) +
"</span>";
}
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrides);
})();
SPClientTemplates.Utility.… encoding helpers or build DOM nodes rather than concatenating strings.
Override points you can hook
- Fields — per field, per mode (
View,DisplayForm,EditForm,NewForm). The most common use: format a single column. - Item — override the rendering of an entire row.
- Header / Body / Footer — restyle the whole view, e.g. render items as cards instead of a table.
- OnPreRender / OnPostRender — run code before and after rendering, useful for wiring up events or third-party widgets.
A view-level transform
To render the whole list as cards you override Header, Item, and Footer together:
var overrides = {
Templates: {
Header: function (ctx) { return "<div class='card-grid'>"; },
Footer: function (ctx) { return "</div>"; },
Item: function (ctx) {
var item = ctx.CurrentItem;
return "<div class='card'><h3>" +
STSHtmlEncode(item.Title) + "</h3><p>" +
STSHtmlEncode(item.ContractStatus) + "</p></div>";
}
}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrides);
STSHtmlEncode is the built-in encoder SharePoint loads on classic pages.
Targeting your override
You can attach JSLink at several scopes, which determines where the override applies:
- Field — set the field's
JSLinkproperty, and the override applies everywhere that field renders. - List View Web Part — set JSLink in the web part properties to affect a single view on a single page.
- Content type — affects forms for items of that type.
The value uses ~ tokens so it resolves correctly regardless of site URL, and can chain multiple files with |:
~sitecollection/Style Library/csr/status-field.js
Set-PnPField -Identity "ContractStatus" -Values @{ JSLink = "~sitecollection/Style Library/csr/status-field.js" }. That makes your formatting deployable and repeatable rather than hand-clicked.
The honest caveats
- Classic only. CSR does not run on modern pages. The modern equivalent for column display is JSON column formatting (covered in a later article); for richer UI it's SPFx.
- Fragile across updates. Because you're hooking an internal rendering pipeline, heavy customisations can break when the platform changes.
- No build tooling. It's raw JavaScript dropped in a library — fine for small overrides, unwieldy for anything large.
Why it still earns a place
If you support classic SharePoint — and many enterprises still run classic team sites and publishing portals — JSLink/CSR remains the lightest way to restyle a column or view without deploying a solution. And conceptually it set the stage for what came next: declarative JSON formatting took the same "format this column in the browser" idea and made it codeless, while SPFx took the "run my JavaScript on the page" idea and gave it a real toolchain. Knowing CSR makes both of those successors click into place.