# Nhan AEM Notes > A personal collection of notes, code snippets, and guides for Adobe Experience Manager (AEM), Java, and web development. ## AEM - [AEM (Adobe Experience Manager)](https://nhanbe.id.vn/aem/index.md): AEM (Adobe Experience Manager) Index - Architecture - Foundation - Backend - Content & Data - UI - Infrastructure - AEM Articles - [AEM Core Architecture](https://nhanbe.id.vn/aem/architecture.md): The core philosophy is everything is content. Pages, components, templates, configurations, code-resolved scripts - they all live as nodes in the JCR. - [Building Homepage & Article Page](https://nhanbe.id.vn/aem/foundation/building-pages.md): Practice: Building component for home page. - [Client Libraries](https://nhanbe.id.vn/aem/foundation/client-libraries.md): Client libraries AEM basic - [Component Dialogs](https://nhanbe.id.vn/aem/foundation/component-dialogs.md): Basic Dialog Structure On Touch UI, all dialogs follow a strict nested XML structure built using Granite UI libraries. - [Content Fragments & GraphQL](https://nhanbe.id.vn/aem/foundation/content-fragments-and-graphql.md): Content Fragments are **structured, channel-neutral content*— text, images, data — stored independently of any page layout. Combined with GraphQL, - [HTL Templates](https://nhanbe.id.vn/aem/foundation/htl-templates.md): HTL (formerly Sightly) is AEM's server-side template language. It completely replaces JSP and serves as the standard for rendering components. HTL' - [Introduction to AEM](https://nhanbe.id.vn/aem/foundation/introduction-to-aem.md): Adobe Experience Manager (AEM) is a content management system (CMS) built on Java. It manages websites, digital assets, and content across channel - [JCR & Sling](https://nhanbe.id.vn/aem/foundation/jcr-and-sling.md): JCR is a hierarchy, tree-structured content repository. JCR has nodes and properties. Nodes are like folders. They have a name, type, and contain - [JCR Page Properties & jcr:content Node](https://nhanbe.id.vn/aem/foundation/jcr-page-properties.md): All properties on the jcr:content node of an AEM page - [OSGi Fundamentals](https://nhanbe.id.vn/aem/foundation/osgi-fundamentals.md): OSGi is the module system managing all Java code in AEM. Every Java piece — your code, AEM's code, third-party libraries — runs inside an **OSGi - [Publishing And Replication](https://nhanbe.id.vn/aem/foundation/Publishing-and-Replication.md): Build pages and assets on the **author*instance. Visitors never see author tier they see publisher, fronted by the Dispatcher and a CDN. Replication - [Sling Model](https://nhanbe.id.vn/aem/foundation/sling-model.md): --**Flow Summary (HTL):*1. `data-sly-use` points to a class annotated with `@Model`. 2. Sling creates an instance and injects fields. 3. HTL use - [Templates & Policies](https://nhanbe.id.vn/aem/foundation/templates-and-policies.md): **Template**: determines **page structure*and **authoring regions**. **Policy**: determines **allowed components*+ **default/design options*+ - [Testing and Debugging](https://nhanbe.id.vn/aem/foundation/testing-and-debugging.md): What it cover: Sling Models, services, utility logic in isolation Tooling: JUnit 5, Mockito, wcm.io AEM Mocks (`AEMContext`) `AEMContext` from - [Your First Component](https://nhanbe.id.vn/aem/foundation/your-first-component.md): Components are the primary building blocks of AEM pages. A button, a text block, a carousel, or a hero banner — each of these elements is a - [Context-Aware Configuration](https://nhanbe.id.vn/aem/backend/context-aware-configuration.md): Sling Context-Aware Configuration (CA Config) lets you store configuration values - [Event Listeners and Handlers](https://nhanbe.id.vn/aem/backend/event-listener-and-handler.md): AEM provides two event systems for reacting to changes in the repository and the platform. Understanding - [AEM Filters](https://nhanbe.id.vn/aem/backend/filters.md): Sling servlet filters sit between the Sling engine and the servlet (or script) that ultimately handles a request. They intercept every request tha - [Java Best Practices in AEM](https://nhanbe.id.vn/aem/backend/java-best-practice-aem.md): This page collects practical Java guidelines for AEM projects. The goal is consistent, safe code that is easy to test and maintain. - [OSGi Configuration](https://nhanbe.id.vn/aem/backend/osgi-configuration.md): OSGi configuration must be deployed via code (content package), not manually edited in Felix Console. Easy PR review Git history tracking - [AEM Servlets](https://nhanbe.id.vn/aem/backend/servlets.md): Sling Servlets are Java classes that handle HTTP requests in AEM. They are the standard way to build - [Sling Jobs and Scheduler](https://nhanbe.id.vn/aem/backend/sling-jobs-and-scheduler.md): AEM's background processing is built on two complementary mechanisms: - [Sling Models and Services](https://nhanbe.id.vn/aem/backend/sling-model-and-services.md): Sling Models are annotation-driven Java classes that automatically map AEM content (JCR properties, - [AEM Workflows](https://nhanbe.id.vn/aem/backend/workflows.md): AEM Workflows are automated, multi-step processes that model real-world business operations inside Adobe - [Content Fragments](https://nhanbe.id.vn/aem/content-and-data/content-fragment.md): Guide to authoring and managing structured Content Fragments in AEM. - [Content Fragments & GraphQL](https://nhanbe.id.vn/aem/content-and-data/content-fragments-and-graphql.md): Delivering structured Content Fragments via AEM GraphQL APIs for headless applications. - [Experience Fragment - XF](https://nhanbe.id.vn/aem/content-and-data/experience-fragment.md): Authoring, managing, and reusing Experience Fragments across channels in AEM. - [Headless GraphQL](https://nhanbe.id.vn/aem/content-and-data/graphql.md): Setting up and executing GraphQL queries for headless content delivery in AEM 6.5. - [i18n và Translation](https://nhanbe.id.vn/aem/content-and-data/i18n-translation.md): Managing UI string translations dictionary and multi-language content in AEM. - [Hướng dẫn Truy vấn & Sửa đổi JCR](https://nhanbe.id.vn/aem/content-and-data/modify-and-query-the-jcr.md): Comprehensive guide for querying and modifying JCR repository nodes and properties. - [Multi-Site Manager (MSM)](https://nhanbe.id.vn/aem/content-and-data/multi-site-manager-msm.md): Managing multi-site blueprints, live copies, and rollout configurations with AEM MSM. - [JCR Node Operations](https://nhanbe.id.vn/aem/content-and-data/node-operation.md): Comparing Sling Resource API and JCR Node API for repository CRUD operations. - [Query Builder](https://nhanbe.id.vn/aem/content-and-data/query-builder.md): In-depth guide to AEM QueryBuilder predicates, pagination, indexing, and optimization. - [Replication và Activation](https://nhanbe.id.vn/aem/content-and-data/replication-activation.md): Understanding AEM replication agents, content activation workflow, and Dispatcher flush mechanism. - [Tags và Taxonomies](https://nhanbe.id.vn/aem/content-and-data/tags-taxonomies.md): Managing JCR tags, taxonomies, and tagging APIs in Adobe Experience Manager. - [Coral Ui](https://nhanbe.id.vn/aem/ui/coral-ui.md): Coral Ui - developer documentation and reference notes for Coral Ui. - [Custom Dialog Widgets](https://nhanbe.id.vn/aem/ui/custom-dialog-widgets.md): Custom Dialog Widgets - developer documentation and reference notes for Custom Dialog Widgets. - [Extending Responsive Grid](https://nhanbe.id.vn/aem/ui/extending-responsive-grid.md): Extending Responsive Grid - developer documentation and reference notes for Extending Responsive Grid. - [Webpack](https://nhanbe.id.vn/aem/ui/multi-tenancy-ui-frontend.md): Webpack - developer documentation and reference notes for Webpack. - [Overlays trong AEM 6.5](https://nhanbe.id.vn/aem/ui/overlays.md): Overlays trong AEM 6.5 - developer documentation and reference notes for Overlays trong AEM 6.5. - [Render Conditions](https://nhanbe.id.vn/aem/ui/render-conditions.md): Render Conditions - developer documentation and reference notes for Render Conditions. - [AEM SPA Editor](https://nhanbe.id.vn/aem/ui/spa-editor.md): AEM SPA Editor - developer documentation and reference notes for AEM SPA Editor. - [Touch UI / Author UI](https://nhanbe.id.vn/aem/ui/touch-ui-2.md): Touch UI / Author UI - developer documentation and reference notes for Touch UI / Author UI. - [Touch Ui](https://nhanbe.id.vn/aem/ui/touch-ui.md): Touch Ui - developer documentation and reference notes for Touch Ui. - [ACL & Permissions](https://nhanbe.id.vn/aem/infrastructure/acl-permissions.md): ACL & Permissions - developer documentation and reference notes for ACL & Permissions. - [AEM Dispatcher, Cache và Flush Cache trong AEM 6.5 On-Premise](https://nhanbe.id.vn/aem/infrastructure/dispatcher-cache-flush.md): Understanding AEM Dispatcher caching mechanics, stat files, and cache invalidation flush agents in AEM 6.5. - [Dispatcher: Cấu hình Cache và Rủi ro](https://nhanbe.id.vn/aem/infrastructure/dispatcher-config-risks.md): Analyzing AEM Dispatcher caching configurations, security rules, and common deployment risks. - [MSM (Multi Site Manager) trong AEM 6.5](https://nhanbe.id.vn/aem/articles/msm/basic-msm-in-aem.md): MSM cho phép nội dung nguồn được tái sử dụng ở nhiều site đích với cơ chế COPY-based. Hướng dẫn chi tiết về Blueprint, Live Copy, Rollout Config, Live Action và API. - [Sling Framework - Basic](https://nhanbe.id.vn/aem/articles/sling/sling-framework.md): Introduction to Apache Sling RESTful framework, resource mapping, and JCR content architecture. - [Sling Model Annotations](https://nhanbe.id.vn/aem/articles/sling/sling-model-annotations.md): Complete reference for Apache Sling Model annotations and field injectors. - [AEM - Code Execute flow](https://nhanbe.id.vn/aem/articles/10-authoring-publishing-dispatcher-code-env.md): Understand the boundaries and execution flow differences between AEM Author, Publish, Dispatcher, and CDN. - [AEM Externalizer — Hướng dẫn sử dụng trong dự án mysite](https://nhanbe.id.vn/aem/articles/aem-externalizer-guide.md): Guide to configuring and using AEM Externalizer service to build absolute URLs across environments. - [Khai thác Classic UI để debug trên AEM hiện đại](https://nhanbe.id.vn/aem/articles/classic-ui-debugging.md): Debugging guide utilizing Classic UI consoles and tools in modern AEM 6.5. - [Cloudflare](https://nhanbe.id.vn/aem/articles/cloudflare-api-cache.md): Best practices for setting up Cloudflare CDN caching in front of AEM API endpoints. - [Touch UI Principal-Based Permission Management](https://nhanbe.id.vn/aem/articles/experience-manager-65-touch-ui-principal-view.md): AEM 6.5 introduces Permissions Management for Users and Groups. The main functionality remains the same as the classic UI, but is more user-friendly - [Hướng dẫn tạo Custom Page Template trong AEM 6.5](https://nhanbe.id.vn/aem/articles/impl_custom_page_template_guide.md): Guide to creating and configuring custom page templates in AEM 6.5. - [Implement SEO JSON-LD Schema cho Page Component](https://nhanbe.id.vn/aem/articles/impl-seo-schema.md): Implementation guide for structured data JSON-LD generation in AEM using Sling Models and HTL. - [User Administration and Security](https://nhanbe.id.vn/aem/articles/security-aem65.md): Overview of user administration, groups, privileges, and security configurations in AEM 6.5. - [SEO LD+JSON: xây dựng object lồng nhau cho AEM Page](https://nhanbe.id.vn/aem/articles/seo-ld-json-nested.md): Advanced guide for building nested JSON-LD structured data objects in AEM. - [Seo Ld Json](https://nhanbe.id.vn/aem/articles/seo-ld-json.md): Fundamental approach for implementing JSON-LD structured data pipeline in AEM. - [Child Resource](https://nhanbe.id.vn/aem/annotations/child-resource.md): The @ChildResource annotation is a Sling Models injector that maps child JCR nodes to Java objects. It is the - [Externalized ValueMap](https://nhanbe.id.vn/aem/annotations/externalized-value-map-value.md): @ExternalizedValueMapValue is a custom Sling Models injector annotation that reads a JCR property (like - [Sling Model Annotations](https://nhanbe.id.vn/aem/annotations/sling-model-annotations-reference.md): This page is a comprehensive reference for all commonly used Sling Model annotations. Each annotation is explained - [Client Libraries](https://nhanbe.id.vn/aem/client-libraries.md): Client libraries (clientlibs) are AEM's mechanism for managing CSS and JavaScript delivery. They provide dependency management, aggregation, - [AEM Components Overview](https://nhanbe.id.vn/aem/component/component-overview.md): An AEM component is a self-contained building block that authors drag onto a page, configure via a dialog, - [AEM Core Components](https://nhanbe.id.vn/aem/component/core-component.md): This post explains, how you can extend the functionality of AEM Core Components. Part 1 focuses on the extension and reusability of the core - [Decoration Tag (cq:htmlTag)](https://nhanbe.id.vn/aem/component/decoration-tag.md): How AEM wraps components in a decoration element, and how to control its tag name and CSS classes with cq:htmlTag. - [Dialog Validation](https://nhanbe.id.vn/aem/component/dialog-validation.md): AEM's Touch UI dialog framework includes a client-side validation system that lets you enforce business - [Templates and Policies](https://nhanbe.id.vn/aem/component/template-and-policies.md): Editable Templates are AEM's modern template system. They let template authors define - [Touch UI Component Dialogs](https://nhanbe.id.vn/aem/component-dialogs.md): The following chapters each present a Coral XML snippet which can be copied into any /components/mycomponent/cqdialog/.content.xml file. - [Custom AEM Components](https://nhanbe.id.vn/aem/custom-component.md): This guide walks through creating a custom AEM component from start to finish. Every artifact is covered: - [HTL Templates (Sightly)](https://nhanbe.id.vn/aem/htl-templates.md): HTL (HTML Template Language), formerly known as Sightly, is AEM's server-side template language. It is the - [Standalone ACS Common Overview](https://nhanbe.id.vn/aem/standanlone-acs-common/acs-common-overview.md): [GitHub Repository](https://github.com/LucaNerlich/standalone-acs-commons) [ACS AEM Commons](https://adobe-consulting-services.github.io/acs-aem-comm - [AEM Advance topic](https://nhanbe.id.vn/aem/advanced/index.md) - [AEM as a Cloud Service](https://nhanbe.id.vn/aem/advanced/aem-as-a-cloud-service.md) - [AEM Client Libraries (Clientlibs)](https://nhanbe.id.vn/aem/advanced/client-libraries.md): #base=css variables.less mixins.less base/typography.less base/layout.less components/product-hero.less components/spec-table.less components/downloads.lessCopy Copy clientlib-product/js.txt #base=js utils/dom.js utils/analytics.js components/spec-table.js components/downloads.js main.jsCopy Copy What to point at in an interview: The #base= line sets the folder, so variables.less means css/variables.less. The ordering is deliberate and load-bearing: variables, then base, then components. Alphabetical order would put base before variables and break every variable reference. main.js is last, because it initialises things the other modules define. 8.3 A component-level clientlib ui.apps/.../apps/energy/components/accordion/clientlibs/.content.xml Copy Copy Note what is absent: allowProxy. That is deliberate, and it is the answer to a good follow-up question. This clientlib is embedded into energy.product and energy.editorial, so the browser never requests it directly. Adding allowProxy here would expose it unnecessarily for no benefit. 8.4 The page component — calling clientlibs correctly ui.apps/.../apps/energy/components/page/page.html CSS in the head, JS at the end of the body. CSS in the head means the browser has styles before it paints, so there is no unstyled flash. A blocking script in the head halts HTML parsing until it downloads and runs. Categories from the page policy, not hardcoded. This is the direct link to file 03. One page component, different bundles per template. async on analytics. Nothing on the page depends on it, so it should never delay anything. 8.5 Reading the page policy's clientlib categories package com.energy.core.models; import com.day.cq.wcm.api.designer.Style; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.ScriptVariable; import javax.annotation.PostConstruct; import java.util.Arrays; import java.util.List; @Model( adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL ) public class PageModel { }Copy Copy The key line is currentStyle.get("clientlibs", ...). currentStyle is the resolved policy for this component on this template — that is the bridge between file 03's page policy and this file's clientlib categories. Note also the model adapts from SlingHttpServletRequest rather than Resource, because @ScriptVariable for currentStyle needs request context. That is a real distinction covered properly in file 05. 8.6 The dispatcher rule that must exist dispatcher/src/conf.dispatcher.d/filters/filters.any (extract) /0001 { /type "deny" /glob "*" } /0100 { /type "allow" /path "/etc.clientlibs/*" /extension '(css|js|jpg|jpeg|png|gif|svg|woff|woff2|ttf|eot)' }Copy Copy Say this in an interview: allowProxy and the dispatcher filter are two independent gates, and both must pass. They produce an identical symptom — a 404 on the CSS — but you tell them apart by whether the request reached AEM at all. Check the dispatcher log; if it never got through, it is the filter. Common Mistakes The mistake What actually happens The fix allowProxy missing on a served clientlib 404 on publish, works on author allowProxy="{Boolean}true" allowProxy="true" without {Boolean} Stored as a string; the proxy ignores it. Looks correct in the XML. Add the type hint Dispatcher not allowing /etc.clientlibs Identical 404, one layer earlier Add the filter rule Missing or empty js.txt No JavaScript at all, silently — no error Create it, list files in order Wrong order in css.txt Variables load after the styles using them; everything breaks subtly Variables → base → components Listing a folder instead of files Alphabetical order, almost always wrong List files explicitly Editing generated css.txt / js.txt Overwritten on the next ui.frontend build Change the webpack config instead Two bundles embedding the same clientlib Code shipped and executed twice; JS handlers bind twice One embedder per component clientlib One giant site-wide bundle Every page downloads everything Split by page type via page policies Hardcoding categories in the page component Every page type gets the same bundle Read them from the page policy allowProxy on component clientlibs that are embedded Unnecessary exposure, more places to get wrong Only page-level bundles need it Assets outside resources/ Relative url() in CSS 404s Put fonts and images in resources/ No versioning on 6.5 Users see stale CSS for days after a deploy ACS Commons Versioned ClientLibs JS in the without defer Blocks HTML parsing, delays first paint End of body, or defer Component JS using IDs / global selectors Two instances on one page conflict Scope to the component's own element Author-only styling in the site bundle Shipped to every visitor for no reason Separate category, included conditionallyBest Practices On structure. Layer it: a base clientlib every page loads, page-type bundles selected by page policy, and component clientlibs embedded into those bundles. Resist the single site-wide bundle — it is the default drift and it is what makes pages slow. On categories. Namespace them — energy.base, energy.product, energy.component.accordion. Be deliberate about sharing a category across folders, because it means requesting that category pulls in all of them. On allowProxy. Set it only on clientlibs the browser actually requests. Embedded ones do not need it. Always use the {Boolean} type hint. On css.txt and js.txt. Order deliberately — variables, then base, then components. List files explicitly rather than folders. If they are generated by ui.frontend, do not hand-edit them. On embed versus dependencies. Embed component clientlibs into bundles to avoid a request per component. Use dependencies only for a genuine ordering requirement. Keep a rule that each component clientlib is embedded by exactly one bundle. On loading. CSS in the head, JS at the end of the body. async for anything nothing depends on, like analytics. media="print" for print styles so they never block rendering. On caching. Versioned URLs, always. On Cloud Service it is built in; on 6.5 use ACS Commons. Then you can safely set a long TTL, which is the actual win. On the front-end workflow. Use ui.frontend so the front-end team gets modern tooling and does not need an AEM instance to work. Debugging Tips The single most useful trick: add ?debugClientLibs=true to any page URL. Instead of one merged, minified file you get the individual source files listed separately and unminified — so you can see exactly what is being included, in what order, and read the actual CSS. The dumplibs tooling — worth memorising at least the first path: /libs/granite/ui/content/dumplibs.html → every clientlib registered, with its categories, dependencies and embeds /libs/granite/ui/content/dumplibs.test.html?categories=energy.product → exactly what a given category resolves to, in order /libs/granite/ui/content/dumplibs.validate.html → flags duplicate categories and other issues /libs/granite/ui/content/dumplibs.rebuild.html → force a rebuild of the generated outputCopy Copy The diagnostic flow for "my styling isn't there": graph TD A["No styling on the page"] --> B{"Is the tag
in the HTML?"} B -->|No| C["Category wrong, or the
page policy has no clientlibs"] B -->|Yes| D{"Does the URL 404
in the network tab?"} D -->|No| E["File loaded — it's a CSS
problem, not a clientlib one"] D -->|Yes| F{"Did the request reach AEM?
check dispatcher.log"} F -->|No| G["DISPATCHER FILTER
blocking /etc.clientlibs"] F -->|Yes| H["ALLOWPROXY
missing or stored as a string"] ⛶ Fullscreen Splitting the problem the same way as always: is the reference wrong, or is the fetch failing? The tag being present tells you the page and the policy are fine, and the problem is delivery. When a change doesn't appear: Rebuild the clientlibs via the dumplibs rebuild page — the generated output is cached. Hard refresh the browser, or check in a private window. Flush the dispatcher. If it is production, remember the CDN. When you suspect duplication: load with ?debugClientLibs=true and look for the same file listed twice, or search the merged output for a distinctive function name. Tool What it tells you ?debugClientLibs=true Individual unminified files, in order dumplibs.html All clientlibs, categories, embeds, dependencies dumplibs.test.html?categories=X What one category actually resolves to dumplibs.rebuild.html Force regeneration Browser network tab Whether the fetch 404s, and the response headers dispatcher.log Whether the request even reached AEM DevTools → Coverage How much of your CSS/JS actually executes 12. Performance Optimization Clientlibs are usually the largest front-end performance lever in an AEM project, so this section matters more than it does in most files. Split by page type. This is almost always the biggest single win. One site-wide bundle means every page downloads the campaign carousel, the interactive map, and the data-table library whether it uses them or not. Page policies make the split free — no code change, just different categories per template. Measure before cutting. Chrome DevTools has a Coverage tab that shows exactly what proportion of each file executes on a given page. Guessing what is unused is how you break things. Load CSS in the head, JS at the end of the body. CSS is render-blocking by design, which is what you want — the page should not paint unstyled. JavaScript blocking the parser is not what you want. Use async and defer appropriately. async for anything nothing depends on and whose order does not matter, like analytics. defer for scripts that need the DOM parsed but should not block it. Non-blocking print styles. media="print" means the browser downloads it at low priority and it never blocks rendering. Versioned URLs plus a long TTL. This is the caching win. Without versioning you cannot safely set a long TTL, because you have no way to force a refresh. With it, you can cache for a year. Watch for embed duplication. Two bundles embedding the same library means shipping it twice. Consider critical CSS for the highest-traffic templates — inline the above-the-fold styles and load the rest asynchronously. Real gain, real maintenance cost; worth it on a landing page, usually not everywhere. Load genuinely heavy, rare things on demand. A map library or video player used on a handful of pages should not be in the main bundle. Numbers worth quoting: aim for well under 200KB of JavaScript on a typical content page, and check Largest Contentful Paint under 2.5 seconds. Real Production ScenariosCSS works on author, missing on publish. allowProxy not set, or set as a string without {Boolean}. The single most common clientlib incident.Same symptom, but allowProxy is correct. The dispatcher is not allowing /etc.clientlibs. Distinguish by whether the request reached AEM.No JavaScript at all, no error. js.txt missing or empty.Styles apply in the wrong order. Wrong order in css.txt, or a folder listed instead of files so it went alphabetical.Users still see old CSS days after a deploy. No versioned URLs. The URL never changed, so nothing refetched.A source change doesn't appear even after a hard refresh. The generated output is cached — rebuild via dumplibs. Then check dispatcher and CDN.A JavaScript event fires twice. The clientlib is duplicated — two bundles embedding the same one, so the handler binds twice.Fonts or background images 404. They are not in the resources/ folder, so the relative path does not resolve through the proxy.Unexpected CSS appearing on a page. Another clientlib declares the same category, so it is included too.Page is slow, huge JavaScript payload. One site-wide bundle. Split by page type using page policies.Component works in isolation, breaks with two on a page. Component JS using IDs or document-wide selectors rather than scoping to its own element.Author-only styling visible to visitors. Authoring clientlib included in the site bundle instead of conditionally.Front-end changes keep getting reverted. Someone is editing the generated css.txt or js.txt by hand instead of the ui.frontend source.Clientlib works locally, missing on the server. Not included in the package filter, so it never deployed.Print stylesheet blocking page render. Loaded without media="print".LESS compilation errors after a merge. A file listed in css.txt no longer exists, or a variable moved after the file that uses it.Category renamed and half the site lost styling. Categories are referenced from page policies too, not just HTL — those need updating as well.Two page types accidentally sharing a bundle. Both templates' page policies point at the same categories.Analytics script delaying first paint. Loaded synchronously instead of async./etc.clientlibs returns 403 rather than 404. Usually an ACL or a dispatcher rule that matches but denies, rather than the path being absent.Follow-up Questions How many clientlibs does your project have? How is your front-end code built — in AEM, or in ui.frontend? Do you write LESS or SASS? How big is the JavaScript payload on a typical page? How do different page types get different bundles? How do you handle cache busting? Have you had the publish 404 problem? Do component clientlibs get embedded or served individually? Who owns the front-end build on your team? What would you change about how your project handles clientlibs? For the last one: "Our base bundle has grown over time — things get added to it because it's the easy place, and nobody removes anything. I'd want a size budget enforced in the build so it fails when the base bundle grows past a threshold."Comparison Tables categories vs embed vs dependencies — the syllabus comparison categories dependencies embed What it is The name this library answers to Load another category first Pull another category inside Direction Names this library Points at others Points at others Result — Separate files One merged file HTTP requests — More Fewer Order guaranteed — Yes Yes (it's one file) Target needs allowProxy — Yes No Use for Naming and grouping jQuery before a plugin Component clientlibs into a bundle Risk Accidental sharing Extra requests Duplication Clientlib locations Pre-6.4 Current Path /etc/clientlibs/ /apps//clientlibs Publicly readable Yes No Served via Directly /etc.clientlibs proxy Needs allowProxy No Yes, if served directly clientlib.all vs .css vs .js Outputs Where to put it clientlib.all Both and