Best Approaches to Client Libraries in Adobe CQ5, Part 1

Best Approaches to Client Libraries in Adobe CQ5, Part 1

Client libraries are an essential building block of an application programming interface (API). A client library is a resource that the API depends on. In other words, when constructing an application, the controller is dependent on the information that the client library resource provides to appear and act as expected.

In this three-part series, we will explore the functionality of the Client Library Folder in Adobe CQ5, colloquially known as the clientlib, and how it can be properly utilized to breathe life into the application.

The concept of the clientlib is central to Adobe CQ5 because it can allow all the JavaScript and CSS resources within the application to be organized intelligently, as well as provide the means to handle dependencies between client libraries. It gives you a great deal of freedom to structure and consolidate client resources, offering a modular platform by which the application can easily import the resources it needs.

But with great freedom also comes great responsibility. There are several ways to go about setting up clientlibs, and we will cover some of the pros and cons of a centralized approach versus a compartmentalized approach.

The Centralized Approach

The centralized approach entails bundling all client libraries into monolithic and all-encompassing.JS and .CSS files within /etc/designs/{project}/clientlibs. This type of clientlib is loaded by default for every page within a project and it doesn’t need to be called explicitly. The biggest obstacle to this is large files that load all the JS and CSS regardless of whether or not the page actually needs it, at the expense of page load performance.

Download Blue Acorn iCi’s Complete Customer Experience Report to learn how to create an unforgettable, personalized customer experience.

The Modular Approach

The modular approach is to create clientlibs at the component level. This keeps the clientlib local to the component. You will create a “categories” property of the String[] type with the value that is descriptive of the type or use of the components within the clientlib. This value will be referenced when including the clientlib in the JSP of a component, as well as defining embedded clientlib inheritance at the template-level.
This categories property is also beneficial because it allows you to group several clientlibs into the same category, so one include can pull as many clientlibs that belong to that category with one CQ include.
For instance, if you place the following CQ includes into the <head>:

<cq:includeClientLib css="project.components" />
<cq:includeClientLib js="project.components" />

It might result in this HTML-output:

<link href="/apps/components/component1/clientlib.css?x36915" rel="stylesheet" type="text/css" />
<link href="/apps/components/component2/clientlib.css?x36915" rel="stylesheet" type="text/css" />
<link href="/apps/components/component3/clientlib.css?x36915" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/apps/components/component1/clientlib.js?x36915"></script>
<script type="text/javascript" src="/apps/components/component2/clientlib.js?x36915"></script>
<script type="text/javascript" src="/apps/components/component3/clientlib.js?x36915"></script>

While this may sometimes be a good thing, the major criticisms to this modular clientlib approach is 1) the resources are retrieved directly from /apps and application structure is exposed, and 2) a number of server calls have to be made to fetch the resources, in the case of grouped clientlibs by category. However, there is a hybrid approach that can be considered the best of both worlds; essentially redirecting these resources which keeps /apps invisible and still allows CQ5 to merge them to single files.

The Hybrid Approach

To do this, you will need to create a clientlib node under /etc/designs/{project}/clientlibs. The etc/designs/project clientlib node will have an embed property of “project.components,” and a category property of “project.all.” By defining this embed property, this template-level clientlib automatically embeds, or inherits, all of the internal component-level clientlib resources with “project.components,” and define its own category called “project.all.” Now when you change the CQ5 includes in the JSP to:

<cq:includeClientLib css="project.all" />
<cq:includeClientLib js="project.all" />

``It will result in a consolidated, template-level clientlib, with HTML-output like this:

<link href="/etc/designs/{project}/clientlib.css?x36915" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/etc/designs/{project}/clientlib.js?x36915"></script>

This approach has all of the merits of a preferred approach, because if you open these files then you will see that the three js/css resources are merged into one file. And although the resources are located in the /apps-folder, all references seem to originate from the /etc/designs folder. So in essence, the component’s JS and CSS is local, the component within the JCR, /apps is obscured from the end-user, and the internal resources are being masked into an external clientlibs file that is kept within /etc and referenced in the component.

Check out our continued exploration of clientlibs in Adobe CQ5, particularly how to optimize your page load time and a summary of the advantages when using a centralized or compartmentalized approach.

If you need help developing your optimization strategy, contact us to learn how we can help.