Article updated on July 27, 2016.

With the introduction in AEM6 of the HTML Template Language (HTL), formerly known as Sightly, I often get the question: “But what about ClientLibs, how do we do that with HTL?”

In this article I will explain you how you can call ClientLibs from HTL, and how to pass them data from the back-end.

Also have a look at my other article that covers in detail how to first setup the ClientLibs folders on the server: AEM Client Libraries explained by example.

Calling Client Libraries from HTL

Because HTL is meant to be a general language, without specific AEM features, there is no data-sly-clientlibs feature for instance.

The best example is from the new foundation page component, this is located at /libs/wcm/foundation/components/page/head.html.

There, you see the following thing:


This declares a “clientlib” object, which is implemented as a template.

After that, you see statements like following one:

data-sly-call="${clientlib.all @ categories='cq.jquery'}"

This will output <script> and a <style> includes to all CSS and JS contained in the parameter “categories”.

You can also call “clientlib.css” and “clientlib.js” if you only want to output the CSS or JS:

data-sly-call="${clientlib.js @ categories='clientlib1,clientlib2'}"
data-sly-call="${clientlib.css @ categories='clientlib1,clientlib2'}"

Notice that the “categories” option can be a comma-separated string, or a list of category names.

Both statements, the data-sly-use and the data-sly-call, can also be placed on a same element:

<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
     data-sly-call="${clientlib.all @ categories='clientlib1,clientlib2'}"/>

The <sly> element has been introduced with AEM 6.1, and before that a data-sly-unwrap attribute had to be added to the element, because we likely don’t want to have a surrounding element around the generated CSS and JS includes.

What matters in files that need to include ClientLibs, is to always first have declared once the data-sly-use.clientlib, or it would show an error “500 data-sly-call: expression evaluates to null. Cannot serve request to template.html on this server.”

Passing Data from HTL to Client Libraries

Another frequent question is how to pass data to from the back-end to the ClientLibs.

The easiest way is generally to use a data attribute that contains the data serialized in JSON format. The ClientLib can then access that data attribute and easily un-serialize it again.

<div data-sly-use.logic="logic.js" data-json="${logic.json}">...</div>

This calls the server-side JavaScript Use-API to generate the serialized JSON, and then simply places it into a data-json attribute.

And this is the logic.js that serializes some sample data:

use(function () {
    var myData = {
        str: "foo",
        arr: [1, 2, 3]
    return {
        json: JSON.stringify(myData)

The rest of the work is then on the ClientLib to parse again the JSON.

This is an example of the corresponding JavaScript to place into the client-side JavaScript of the ClientLib:

var elements = document.querySelectorAll("[data-json]");
for (var i = 0; i < elements.length; i++) {
    var obj = JSON.parse(elements[i].dataset.json);

I hope this article has made it easier to understand how to use ClientLibs in HTL, and how to pass data from the HTL back-end to the front-end ClientLibs.



Other posts on the topic:

And here other resources to learn more about it:


where is cq.jquery category defined?