Day 19 of 40
WKND: Client-Side Libraries
Categories, embed, dependencies, allowProxy and the proxy servlet
By the end of today you should be able to
- Create a client library and understand categories, dependencies and embed
- Explain allowProxy and why clientlibs are served from /etc.clientlibs
- Include clientlibs correctly from a page component
- Debug a clientlib that is not loading
What a client library is
A client library (clientlib) is AEM's mechanism for serving CSS and
JavaScript. It is a node of type cq:ClientLibraryFolder containing your source files plus
two text files listing which of them to include and in what order:
/apps/wknd/clientlibs/clientlib-site
.content.xml jcr:primaryType = "cq:ClientLibraryFolder"
categories = ["wknd.site"]
allowProxy = true
css.txt
js.txt
css/
js/
css.txt lists files relative to a base directory:
#base=css
site.css
components.css
AEM concatenates and (in production) minifies the listed files into a single response, so the browser makes one request per category rather than one per file.
Categories, dependencies, embed
- categories — the name(s) by which this library is requested. Multi-valued: a library can belong to several categories.
- dependencies — categories that must be loaded before this one. They are included as separate requests.
- embed — categories whose content is copied into this library's output. One request, contents merged.
dependencies says "load that too, first". embed says "fold that into me". Embed is how you expose a library that lives somewhere non-public: embed it into a proxy-enabled library and its code is served without exposing its path.
allowProxy and /etc.clientlibs
Clientlibs live under /apps, but /apps must not be readable by anonymous
users on publish — exposing it would leak your component structure. The
proxy servlet resolves this: with allowProxy = true, a library
at /apps/wknd/clientlibs/clientlib-site is served from
/etc.clientlibs/wknd/clientlibs/clientlib-site.css.
Nothing actually lives at /etc.clientlibs — it is a virtual path the servlet maps back to
/apps (and /libs). Your Dispatcher must allow /etc.clientlibs in
its filters, which the standard configuration does.
Styles work on author and vanish on publish. The cause is almost always allowProxy not set to true: on author you are logged in and can read /apps directly, while an anonymous visitor on publish cannot.
Including clientlibs
The modern approach uses the Core Components clientlib helper, which gives you control over loading strategy:
<sly data-sly-use.clientlib="core/wcm/components/commons/v1/templates/clientlib.html"/>
<!-- In <head> -->
<sly data-sly-call="${clientlib.css @ categories='wknd.site'}"/>
<!-- Before </body> -->
<sly data-sly-call="${clientlib.js @ categories='wknd.site'}"/>
<!-- Both at once -->
<sly data-sly-call="${clientlib.all @ categories='wknd.site'}"/>
Splitting CSS into the head and JS before the closing body tag is the standard performance shape, and
it is why clientlib.all is usually the wrong choice for a page component.
Debugging
- Does the category resolve? Go to
/libs/granite/ui/content/dumplibs.html— it lists every registered library and its category. A typo incategoriesshows up instantly. - Is it proxy-enabled? Request
/etc.clientlibs/<path>.cssdirectly. A 404 meansallowProxyis missing. - Are the files listed? A file present in the folder but absent from
css.txtis simply not served. This is a very common oversight. - Is it cached? Append a cache-busting query or flush the Dispatcher; stale clientlibs are common after a deploy.
dumplibs.test.htmllets you check which libraries a given category actually pulls in, including embeds.
How ui.frontend fits
In an archetype project you rarely hand-write clientlib-site. The
ui.frontend webpack build produces it: you write Sass and ES modules there, and the build
generates the clientlib folder — css.txt, js.txt and all — into
ui.apps. Editing the generated clientlib directly is a mistake; the next build overwrites it.
Categories name a library, dependencies load alongside, embed folds in. allowProxy = true and /etc.clientlibs are what make it work for anonymous visitors on publish.
Watch
Adobe's own videos for this topic. They load only when you press play.
Read on Experience League
The primary sources these notes are drawn from.
Your notes
Saved automatically to this browser.
Check yourself
10 questions on today's material. 80% to pass.