Arti­cle updat­ed on July 27, 2016.

With the intro­duc­tion in AEM6 of the HTML Tem­plate Lan­guage (HTL), for­mer­ly known as Sight­ly, I often get the ques­tion: “But what about ClientLibs, how do we do that with HTL?”

In this arti­cle 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 oth­er arti­cle that cov­ers in detail how to first set­up the ClientLibs fold­ers on the serv­er: AEM Client Libraries explained by exam­ple.

Calling Client Libraries from HTL

Because HTL is meant to be a gen­er­al lan­guage, with­out spe­cif­ic AEM fea­tures, there is no data-sly-clientlibs fea­ture for instance.

The best exam­ple is from the new foun­da­tion page com­po­nent, this is locat­ed at /libs/wcm/foundation/components/page/head.html.

There, you see the fol­low­ing thing:


This declares a “clientlib” object, which is imple­ment­ed as a tem­plate.

After that, you see state­ments like fol­low­ing one:

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

This will out­put <script> and a <style> includes to all CSS and JS con­tained in the para­me­ter “cat­e­gories”.

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

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

Notice that the “cat­e­gories” option can be a com­ma-sep­a­rat­ed string, or a list of cat­e­go­ry names.

Both state­ments, the data-sly-use and the data-sly-call, can also be placed on a same ele­ment:

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

The <sly> ele­ment has been intro­duced with AEM 6.1, and before that a data-sly-unwrap attribute had to be added to the ele­ment, because we like­ly don’t want to have a sur­round­ing ele­ment around the gen­er­at­ed CSS and JS includes.

What mat­ters 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: expres­sion eval­u­ates to null. Can­not serve request to template.html on this serv­er.”

Passing Data from HTL to Client Libraries

Anoth­er fre­quent ques­tion is how to pass data to from the back-end to the ClientLibs.

The eas­i­est way is gen­er­al­ly to use a data attribute that con­tains the data seri­al­ized in JSON for­mat. The ClientLib can then access that data attribute and eas­i­ly un-seri­al­ize it again.

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

This calls the serv­er-side JavaScript Use-API to gen­er­ate the seri­al­ized JSON, and then sim­ply places it into a data-json attribute.

And this is the logic.js that seri­al­izes some sam­ple 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 exam­ple of the cor­re­spond­ing 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 arti­cle has made it eas­i­er to under­stand how to use ClientLibs in HTL, and how to pass data from the HTL back-end to the front-end ClientLibs.



Oth­er posts on the top­ic:

And here oth­er resources to learn more about it:


where is cq.jquery category defined?