All about CQ clientlibs

Let’s say you are developing a custom CQ component then the key requirement is to include a combination of CSS and JS files in your page. Of course, in CQ you can edit the cq page templates of your website and include those files required for component but this is not one of best designs for a couple of reasons:

  1. Including client-side files in templates increases you page overhead because these files will be included in all pages whether they are needed or not;
  2. Your component will not be portable. If your rely on includes in the templates, then if you wanted to re-use your component on some other instance of CQ, you would have to manually touch the site templates to ensure that your component has the necessary JS and CSS files.

Clientlibs is a convenience wrapper for the com.day.cq.widget.HtmlLibraryManager service interface. This service manages the client side includes like JS and CSS to manage which files should be included in the page as well as ensuring duplicate files are not sent. Using clientlibs in CQ is really easy, once you know what to do that is :) . There are two major steps in this, one is to create jcr nodes in the repository that includes these files and another step is to include these files in your component.

CQ client library folders provide a mechanism for storing, organizing, and dynamically building and serving libraries on request. Create a cq:ClientLibraryFolder node to define JavaScript and Cascading Style Sheet libraries and make them available to HTML pages like following:

clientLib1

You can set the following properties on the new node:

Name Type Value Description
categories String[] client.mycomponent1 Absolute key used to reference this library in html page.
dependencies String[] cq.jquery The value of the categories property of the other cq:ClientLibraryFolder nodes that the current library folder depends on.
embed String[] client.mycomponent2 The value of the categories property of the other cq:ClientLibraryFolder nodes to embed.

The dependencies property tell the CQ rendering engine to make sure that the jquery libraries are included in the page. CQ uses comes with jQuery libraries as they are used for built-in product features.  The categories property is absolutely key. We’ll see in another step that the category name will be used to tell CQ which clientlibs must be included with the html that will be generated. In fact, the cq.jquery we specified for the dependencies is a category. CQ uses categories to identify client libraries to be included.

Client library folders contain the following items:

  • The JS and/or CSS source files to merge.
  • Resources that support CSS styles, such as image files. You can use subfolders to organize source files.
  • One js.txt file and/or one css.txt file that identifies the source files to merge in the generated JS and/or CSS files.

The node contains one or more source files that, at runtime, are merged into a single JS and/or CSS file. The name of the generated file is the node name with either the .js or .css file name extension. For example, the library node named cq.jquery results in the generated file named cq.jquery.js or cq.jquery.css.

The content of css.txt and js.txt would look like following:

#base=javascript
one.js
two.js

Here “base” is to specify the name of the subfolder and “one.js” and “two.js” are files. You can have multiple “base” properties inside the js.txt file. In the similar way you can construct css.txt file.

Once you are done with creating clientlib folders you can just add a cq:includeClientLib tag to your JSP code to add a link to client libraries in the generated HTML page. To reference the libraries, you use the value of the categories property of the cq:ClientLibrary node.

For example, the /etc/clientlibs/foundation/jquery node is of type cq:ClientLibraryFolder with a categories property of value cq.jquery. The following code in a JSP file references the libraries:

<cq:includeClientLib categories="cq.jquery"/>

The generated HTML page contains the following code:

<script type="text/javascript" src="/etc/clientlibs/foundation/jquery.js"></script>

All the dependencies (specified as “dependencies” property at clientlib node) will also be included in the generated HTML. In some cases you may find that the final HTML generated for typical page by your publish instance includes a relatively large number of <script> elements, particularly if your site is using client context information for analaytics or targeting. For example, in a non-optimized project you might find the series of <script> elements in the HTML for a page. In such cases, it can be useful to combine all the required client library code in to a single file so that the number of back and forth requests on page load is reduced. To do this you can embed the required libraries into you app-specific client library using the embed property of the cq:ClientLibraryFolder node.

I consider it as best practice to put the clientlibs under the /apps folder as long as there is a clientlib outside of the /apps folder (typically in the /etc/designs) folder that concatenates them all into one file. That way you can have the CSS and JS where they belong to, right next to the JSP that contains the associated markup and still merge them together into one file that is located in /etc/designs.

There are two very convenient tools that you need to know when you are working with clientlibs:
1. if you access your page with the ?debugClientLibs=true argument in the path, it will include individual JS / CSS files again on the fly, which helps during debugging in Firebug etc.
2. you can see a list of the different clientlibs of your instance through the following url, which again helps debugging:

http://localhost:4502/libs/cq/ui/content/dumplibs.html

3 Comments

  1. Praveen Modi says:

    Excellent article Raghavendra. Very useful. Thank you!

    Like

  2. Anonymous says:

    Thank you for excellent explanation…

    Like

  3. Federico says:

    Interesting article. You mention other resources such image files to support the css. Do you know how these other resources should be handled? Even Adobe’s guides seem to suggest that going through /apps is ok for them (https://docs.adobe.com/docs/en…, url(../../../apps/myapp/clientlib/styles/images/bg-full.jpg). Should those assets just go to the /etc/design folder?

    Like

Leave a Comment