Custom AEM Clientlib Markup for HTML5

Adobe Experience Manager | AEM/CQ | Apache Sling

Custom AEM Clientlib Markup for HTML5

AEM clientlibs are extremely powerful. They allow you to produce client-side JavaScript and CSS libraries while controlling minification, concatenation, and dependency management. However, out-of-the-box, they don't allow you to customize the HTML output. While optimizing your website for speed, you may want to use the defer, async, and/or onload attributes on your script elements. Likewise, while managing your cross-origin resource sharing (CORS) HTTP requests, you may want to utilize the crossorigin attribute on your script and/or link elements for JavaScript and CSS.


Using clientlibs in AEM with Sightly is demonstrated in the AEM documentation Using Client-Side Libraries, as well as Feike Visser's ( @heervisscher) Sightly intro part 5: FAQ.



When we follow the data-sly-use block's expression value in our AEM instance, we find three files that work together with the HtmlLibraryManager to provide the final clientlib output. clientlib.html contains named Sightly template blocks ( js, css, all), which in turn set the proper Sightly expression option for mode and call the named Sightly templates in graniteClientLib.html. graniteClientLib.html then sets the proper Sightly expression options and delegates the more complex logic to a Java-Use API POJO. ClientLibUseObject.java then utilizes the HtmlLibraryManager in order to write out the final HTML markup.

All files associated with Sightly clientlibs are viewable in your AEM instance under the /libs/granite/sightly/templates node. To make any alterations, we simply copy all three files out of /libs into /apps, update the files, and update our Sightly components to point to the new clientlib component (usually headlibs.html or similar partial in the page component).



In our case, we want to alter the HTML markup by adding additional attributes to the script and link elements. In order to do that, we first add additional Sightly expression options to all the Sightly templates. In this example, I'm using loading, onload, and crossorigin options.



Once the new Sightly expression options are set, the Java-Use POJO is updated to obtain those options from the provided bindings. AEM hands the responsibility of printing the final HTML markup to the HtmlLibraryManager's writeIncludes, writeCssInclude and writeJsInclude methods. However, since we want custom markup, we need to do that ourselves in the POJO.



I've written a demonstration AEM project as well provided the code which can easily be installed into a single folder for use in your project. There is also an AEM package available for easy install. View the AEM Clientlib Async project on GitHub.

6 comments

Nono Junang | June 06, 2016 at 07:58 AM | Reply

Nice, Let's say I load a client lib with the option async or defer, do all its dependencies also get loaded with the same options (async or defer)? Cheers, Nono

Jason | April 06, 2017 at 09:42 AM | Reply

I don't think dependencies are added like this. Changing the last "false" on line 197 of ClientLibUseObject.java to "true" seems to load dependencies.

Himi | May 23, 2017 at 12:57 AM | Reply

Thanks for sharing the implementation. It is really helping us. We are now planning to use ACS commons versioned clientlibs however it seems rewrite is not happening like clientlibs.ACSHASHa4a8665a4aa416b3044a3155a22a2e06.css" Do you have any suggestion to make it work with versioned clientlibs ?

Luca Nerlich | January 25, 2018 at 08:52 AM | Reply

VersionedClientLib checks if the 'type="text/javascript" ' attribute is present. Just add it to your js_tag string constant and the VersionedClientLib should append md5 checksums

Luca Nerlich | January 25, 2018 at 08:53 AM | Reply

or 'type="text/css"' respectively

Jake Bowers | February 07, 2018 at 03:55 PM | Reply

Where does the ClientLibUseObject.java class get compiled in AEM and how can I force it to recompile? I've made changes to it, but it doesn't appear to reflect.

Leave a Comment