N
Naveenr.dev
Chapter 01
16 min read2026-06-17

AEM Clientlibs Complete Notes

A complete guide to AEM Client Libraries, covering clientlib properties, setup, dependency handling, proxying, and page inclusion strategies.

Content Objective

  • What are AEM Clientlibs?
  • Why Clientlibs matter in AEM
  • Key Clientlib properties
  • Clientlib folder structure
  • Creating clientlibs in CRX/de
  • Testing clientlibs in AEM
  • What /etc.clientlibs means
  • How to include clientlibs on a page
  • Dynamic clientlib loading
  • Loading clientlibs in dialogs
  • Environment-specific loading

Before we jump into AEM Clientlibs, let’s first look at how JavaScript and CSS files are managed in a typical web development project.

Let’s take the example of a simple HTML-based project. You might be tempted to include multiple CSS and JavaScript files separately in the <head> tag or right before </body> as follows:

<head>
  <link rel="stylesheet" href="styles/reset.css">
  <link rel="stylesheet" href="styles/layout.css">
  <link rel="stylesheet" href="styles/theme.css">
  <script src="scripts/jquery.js"></script>
  <script src="scripts/main.js"></script>
  <script src="scripts/slider.js"></script>
</head>

This method of including styles has its disadvantages

  • Every CSS and JS file creates a separate HTTP request, which can slow down page load.
  • If main.js depends on jquery.js, and the loading order is reversed, the page can break.
  • A developer must manually combine and minify many files to improve performance.
  • Cached files may persist unless file names are changed after updates.

How AEM Solves This with Clientlibs

AEM makes it easy to manage multiple styles and scripts using Client Libraries (Clientlibs). Instead of manually adding multiple scripts and styles, AEM bundles them, handles dependencies, and applies minification and caching automatically.

What are Clientlibs?

  • In Adobe Experience Manager (AEM), Client Libraries manage front-end files like JavaScript, CSS, images, and fonts.
  • Instead of manually adding multiple files, Clientlibs bundle and organize them efficiently.
  • Clientlibs improve page performance by reducing the number of HTTP requests and ensuring files load in the correct order.

Key Features of Clientlibs

  • Clientlibs combine multiple JavaScript and CSS files into a single bundle to reduce HTTP requests.
  • Minification removes unnecessary characters and comments to reduce file size.
  • Clientlibs can declare dependencies on other clientlibs, ensuring correct load order.
  • AEM handles caching automatically by fingerprinting files based on content.
  • Different clientlibs can be created for different themes or device types (for example, mobile vs desktop).

Properties of Clientlibs

1. categories (Required)

  • Used to identify a Clientlib category uniquely.
  • Clientlibs can have multiple categories, which allows them to be included in different places.
Name: categories
Type: String[]
Value: [your-project.category]

2. allowProxy (Optional)

  • Determines whether the clientlib can be accessed through AEM’s Client Library Proxy Servlet.
  • allowProxy = true: Accessible via /etc.clientlibs, hiding its actual location.
  • allowProxy = false: Must be accessed directly through the clientlib path.

When to use allowProxy = false?

  • Use it for internal resources that are not meant for public access.
  • Useful for sensitive or development-specific libraries.
Name: allowProxy
Type: Boolean
Value: true

3. dependencies (Optional)

  • Dependencies ensure that one clientlib loads before another.
  • Use it to load shared resources or base libraries first.

Example:

Name: dependencies
Type: String[]
Value: [desktop]

4. embed (Optional)

  • Combines multiple client library categories into one.
  • If category A embeds categories B and C, the resulting CSS and JS are merged.
Name: embed
Type: String[]
Value: [your-project.base, your-project.components]

5. jsProcessor (Optional)

  • Controls JavaScript minification.
  • Common values:
    • min:gcc — Google Closure Compiler
    • min:yui — YUI Compressor
    • min:none — No modification
Name: jsProcessor
Type: String[]
Value: [min:yui]

6. cssProcessor (Optional)

  • Controls CSS minification.
  • Common values:
    • min:none
    • min:yui
    • min:cssnano
Name: cssProcessor
Type: String[]
Value: [min:cssnano]

7. replaces (Optional)

  • Replaces another Clientlib completely.
  • Useful for overriding default AEM libraries.
Name: replaces
Type: String[]
Value: [cq.desktop]

8. serializationType (Optional)

  • Controls how clientlib files are merged and delivered.
  • flat — Delivers files as individual requests.
  • deep — Merges all files into a single response.
Name: serializationType
Type: String
Value: flat

How to Create Clientlibs Using CRX/de

  1. Open CRX/de: http://localhost:4502/crx/de/index.jsp
  2. Navigate to /apps/project-name/clientlibs.
  3. Right-click the clientlibs folder and choose Create → Node.
  4. Select node type cq:ClientLibraryFolder.
  5. Choose a name for the clientlib.
  6. Create css and js folders to hold your files.
  7. Create a sample.js and sample.css file.
  8. Add a js.txt file inside the js folder listing the JavaScript files.

Example js.txt:

#base=js
sample.js

Create css.txt inside the css folder listing the CSS files.

#base=css
site.css

Testing Clientlibs

  • After creating the folder structure, test the clientlib URL.
  • Example:
http://localhost:4502/apps/AEM-DeveloperResource/clientlibs/custom_clientlibs.js

Setting Clientlib Properties

After creating the clientlib folder, add properties such as:

  • categories
  • allowProxy
  • dependencies
  • embed
  • jsProcessor
  • cssProcessor

What is /etc.clientlibs in AEM?

  • /etc.clientlibs is a proxy path where AEM serves client-side resources.
  • It hides the actual resource locations under /apps or /libs.
  • AEM uses it to improve security and caching.

Why use /etc.clientlibs?

  • Security: Masks actual paths.
  • Performance: Enables minification and caching.
  • Correct loading: Maintains script/style order.
  • Lazy loading support: Loads resources only when needed.

Example Clientlib Definition

If you have a clientlib at /apps/your-project/clientlibs-site with:

- jcr:primaryType = "cq:ClientLibraryFolder"
- categories = ["your-project.site"]
- allowProxy = true

Then AEM exposes it as:

/etc.clientlibs/your-project/clientlibs-site.min.css
/etc.clientlibs/your-project/clientlibs-site.min.js

How to Include Clientlibs on a Page

1. Add clientlibs to page policies

  • Use Page Policies to include clientlibs at the template level.
  • This ensures the same libraries load for all pages using that template.

Steps:

  • Go to AEM > Tools > General > Templates.
  • Open the template to modify.
  • Enter Structure Mode.
  • Select the Page Root container.
  • Open the Policy panel.
  • Add the clientlib category in the policy.

This loads dependencies in the correct order, such as:

  • desktop loads before custom-clientlibs
  • custom-clientlibs loads next

Example policy snippet

<page jcr:primaryType="nt:unstructured">
  <policy
      jcr:description="Include Client libraries."
      jcr:primaryType="nt:unstructured"
      jcr:title="Page Component"
      sling:resourceType="wcm/core/components/policy/policy"
      clientlibs="[desktop,custom-clientlibs]"
      clientlibsJsHead="desktop">
      <jcr:content jcr:primaryType="nt:unstructured"/>
  </policy>
</page>

2. Add clientlibs with JavaScript Use-API

AEM’s JavaScript Use-API lets you include clientlibs dynamically in a component.

<sly data-sly-use.clientlib="core/wcm/components/commons/v1/templates/clientlib.html">
  <sly data-sly-call="${clientlib.all @ categories='AEM-DeveloperResource.base'}"/>
</sly>
<sly data-sly-call="${clientlib.css @ categories='practice.base'}"/>
<sly data-sly-call="${clientlib.js @ categories='practice.base'}"/>

3. Loading Clientlibs Dynamically for Specific Components

  • Load clientlibs only when a specific component renders.
  • This optimizes performance by avoiding unnecessary resource loading.

Example:

<sly data-sly-use.clientlib="core/wcm/components/commons/v1/templates/clientlib.html">
  <sly data-sly-test="${component.enabled}">
    <sly data-sly-call="${clientlib.all @ categories='your-component-clientlib'}" />
  </sly>
</sly>

data-sly-use.clientlib

  • Imports the clientlib helper script for dynamic inclusion.

data-sly-test

  • Checks a condition such as ${component.enabled}.
  • Includes the clientlib only when true.

Example variants

<sly data-sly-call="${clientlib.css @ categories='your-component-clientlib'}" />
<sly data-sly-call="${clientlib.js @ categories='your-component-clientlib'}" />

4. Loading Clientlibs When a Dialog Opens

When a component dialog opens in Touch UI, you may need extra JS or CSS for the dialog.

Steps:

  1. Create a clientlib folder inside the component.
/apps/custom/division/components/button/clientlibs
  1. Add files:
  • js.txt in the js folder
  • dialog.js inside js
  • set allowProxy = true
  1. Add extraClientlibs to the dialog configuration.
  2. Open the dialog in AEM and verify the clientlib loads.

Example script:

$(document).on("dialog-ready", function() {
  console.log("Dialog has opened!");
});

Use cases

  • Initialize custom dialog scripts.
  • Add event listeners when a dialog opens.
  • Load styles only needed inside the dialog.

5. Environment-Specific Loading

You can conditionally load clientlibs in HTL based on editor or preview mode.

<sly data-sly-use.clientlib="core/wcm/components/commons/v1/templates/clientlib.html">
  <sly data-sly-test="${wcmmode.edit}">
    <sly data-sly-call="${clientlib.all @ categories='editor-clientlibs'}" />
  </sly>
  <sly data-sly-test="${wcmmode.disabled}">
    <sly data-sly-call="${clientlib.all @ categories='user-clientlibs'}" />
  </sly>
</sly>

Summary

AEM Clientlibs are the recommended way to manage front-end assets in AEM. They provide:

  • faster page performance
  • dependency-aware loading
  • automatic minification and caching
  • proxy access through /etc.clientlibs
  • flexible inclusion via page policies, JS Use-API, and component conditions