Loading Now

AEM Component Placement Strategies: Overlay, Override, and Resource Merge

aem-placement-strategy

AEM Component Placement Strategies: Overlay, Override, and Resource Merge

Adobe Experience Manager (AEM) gives you three core patterns to place and customize components safely and upgrade‑friendly: Overlay, Override, and Resource Merge. Choosing the right strategy depends on what you want to change (UI, dialog, rendering, configuration), how broadly the change should apply, and whether you need inheritance or a full copy.

This article explains each approach, how it appears to authors (e.g., in Sidekick/Component Browser), plus best practices and pitfalls – especially for AEM 6.5 and AEM as a Cloud Service.


Quick definitions

  • Overlay — Copy the node(s) from ‘/libs/…’ to the **same path** under ‘/apps/…’. AEM’s search path prefers ‘/apps’ over ‘/libs’, so your overlay takes priority. This is ideal for customizing product UI or OOTB configuration without touching ‘/libs’. [reference]
  • Override (via ‘sling:resourceSuperType’) — Create a new component under ‘/apps/…’ that inherits from an existing component (in ‘/libs’ or ‘/apps’) by setting ‘sling:resourceSuperType’. Only the parts you redefine are overridden; everything else is inherited. [reference]
  • Resource Merge (Sling Resource Merger) — A Sling service that merges properties and child nodes coming from original (‘/libs’) with your customization (‘/apps’). It powers both overlays (search path) and overrides (super type hierarchy), and adds special merge directives like ‘sling:hideProperties’, ‘sling:hideChildren’, and ‘sling:orderBefore’. [reference]

1) Overlay

What it is — Overlaying means duplicating the node structure from ‘/libs’ to ‘/apps’ at the same relative path (e.g., ‘/libs/cq/core/content/nav/projects’ → ‘/apps/cq/core/content/nav/projects’) and then modifying the copy. Because AEM looks in ‘/apps’ first, your overlay wins during resolution. [reference]

Authoring impact — If you overlay a component and keep the same ‘jcr:title’ and ‘componentGroup’, authors may see both versions in the component browser (often distinguished by group name or parentheses). That’s typical when overlays duplicate discoverability metadata; design mode can show source group differences.

When to use

  • Customizing consoles, content finder tabs, siteadmin panels, or other product UI under Granite/touch UI, where copying the skeleton under ‘/apps’ is recommended.
  • Tweaking labels, order, or default configuration of OOTB UI without inheritance semantics.

Do’s and Don’ts

  • Do not change ‘/libs’ — it’s overwritten on upgrade/hotfix. Always place customizations in ‘/apps’.
  • For Granite/touch UI, prefer minimal skeleton overlays (not full copies) so the Resource Merger can reference the original and you copy only what you need.
  • Be aware that some Cloud Service areas are immutable or marked ‘granite:InternalArea’; overlays there are restricted — consider extension points instead.

2) Override (Component Inheritance with ‘sling:resourceSuperType’)

What it is — You create a brand‑new component node (e.g., ‘/apps/<project>/components/mytext’) with ‘jcr:primaryType = cq:Component’ and set:

sling:resourceSuperType = <base component path>

This defines a type hierarchy: your component inherits dialogs, scripts (HTL/JSP), clientlibs, and edit config from the parent until you provide local overrides.

Authoring impact — Because it’s a new component, it appears in addition to the original (assuming you publish it with its own ‘jcr:title’ and ‘componentGroup’). Authors can choose either.

Why choose override

  • You want to extend behavior (add fields, change rendering) while retaining all future upgrades of the base component.
  • You prefer composable inheritance over copying nodes. This keeps upgrades smoother and custom code smaller.

Key points

  • ‘sling:resourceSuperType’ drives inheritance resolution. If you also set ‘sling:resourceType’ on content instances, Sling will resolve via the resource type and then use super types. Defining ‘sling:resourceSuperType’ on the component definition is the standard practice.
  • You can inherit from custom components under ‘/apps’ as well, not just ‘/libs’.

3) Resource Merge (Sling Resource Merger)

What it is — A service that merges overlay/override resources. For overlays, it uses search paths (‘/apps’ first, ‘/libs’ second). For overrides, it uses the resource type hierarchy via ‘sling:resourceSuperType’. Your custom nodes and properties take priority; the rest fall back to the original.

Merge directives you can use

  • ‘sling:hideProperties’: hide specific properties (or ‘*’ to hide all) from the merged view.
  • ‘sling:hideChildren’: hide specific child nodes (or ‘*’).
  • ‘sling:hideResource’: hide an entire resource (including children).
  • ‘sling:orderBefore’: reorder sibling nodes.

Classic examples — Extending content finder / asset finder: add more options by placing nodes under ‘/apps’ with the same structure; Resource Merger combines them. (Older classic‑UI guides show how tabs/filters can be added; the modern principle remains: copy only needed nodes and let merge do the rest.)

Scope limitations — Resource Merger applies to Granite/touch UI. For classic UI or non‑Granite areas, you may need to copy full structures.


How they show up to authors (Sidekick/Component Browser)

  • Overlay: If your overlayed component retains the same ‘jcr:title’/’componentGroup’ as the original, both may be visible. Authors might see them differentiated by group or by parenthetical hints (e.g., foundation vs project). Adjust titles/groups if you want only your version discoverable.
  • Override: Always a new component; both the parent and your extended component can be enabled in design/policy and will appear separately.

Choosing the right strategy

ScenarioPreferRationale
Customize AEM consoles, editor panels, or labelsOverlay + Resource Merge  Search path prioritizes ‘/apps’; copy only necessary nodes for Granite UIs.
Create a new component that reuses an existing one’s functionalityOverride (‘sling:resourceSuperType’)Inherit behavior; override only what’s needed; upgrade‑friendly.
Add or remove fields in a cq:dialogOverride (or overlay dialog nodes)Overriding is cleaner; Resource Merger merges untouched parts automatically.
Hide or reorder child nodes without copying full structuresResource Merge directivesUse ‘sling:hideChildren’, ‘sling:orderBefore’ to tweak only what’s necessary.
AEM as a Cloud Service with restricted internal areasOverrides / Extension pointsSome overlays are blocked; consider App Builder UI extensions for product UIs.

Best practices & guardrails

  1. Never modify ‘/libs’; always customize under ‘/apps’. Your changes in ‘/libs’ will be lost on updates.
  2. Minimize copied structure. For Granite/touch UI overlays, reconstruct only the skeleton and let Resource Merger reference the rest—this reduces upgrade risk.
  3. Prefer overrides over overlays for components. If you need inheritance and future upgrades, ‘sling:resourceSuperType’ is safer and cleaner than copying whole components.
  4. Control discoverability. Set unique ‘jcr:title’/’componentGroup’ so authors understand which component to use; otherwise, both versions might appear.
  5. Know your UI surface. Resource Merger applies to touch UI (Granite). For classic UI, overlays may require full copies.
  6. Cloud Service nuances. Some internal Granite areas are immutable; leverage extension points (e.g., CF Editor / Universal Editor APIs) for safe customization.

Common pitfalls

  • Overlaying Core Components: Components that live under ‘/apps’ (e.g., Core Components) cannot be overlaid — they’re already in ‘/apps’. Extend them via ‘sling:resourceSuperType’ instead.
  • Copying too much from ‘/libs’: Full copies increase maintenance and break on upgrades. Copy only what you need for Granite overlays and use merge directives.
  • Setting super type at content nodes: Prefer defining ‘sling:resourceSuperType’ at the component definition rather than content instances; it keeps hierarchy predictable.

Examples (patterns you can adapt)

1. Override a Core/Text component

      Create ‘/apps/<project>/components/text-plus’ as ‘cq:Component’, set:

      jcr:title = "Text Plus"
      componentGroup = "<Project> – Content"
      sling:resourceSuperType = "core/wcm/components/text/v2/text"

      Add only the dialog fields or HTL you need to change; everything else is inherited.

      2. Overlay the Sites navigation label

      Mirror ‘/libs/cq/core/content/nav/projects’ under ‘/apps/cq/core/content/nav/projects’ and change the ‘jcr:title’. The overlay takes precedence in the UI.

      3. Add an Asset Finder filter (classic UI era pattern)

      Copy the relevant filter tab node under ‘/apps’ following the same structure; adjust querybuilder predicates. Resource Merger lets your nodes extend the built‑in panel.


      Extra information (often missed)

      • Search path order is configurable (Apache Sling Resource Resolver Factory), but changing it is not recommended; stick to ‘/apps’ first, then ‘/libs’.
      • Clientlibs belong under ‘/apps/<project>/clientlibs’ for custom code; ‘/apps/settings’ is intended for OOTB assets/settings in newer structures.
      • Cloud Service: The Resource Merger still powers overlays/overrides for touch UI, but the docs emphasize that you reduce replicated structure and avoid ‘/libs’ changes.
      • Merge properties cheat‑sheet (put on nodes under ‘/apps’ to control the merge):
        • ‘sling:hideProperties = [“propA”,”propB”]’
        • ‘sling:hideChildren = [“childA”,”childB”]’
        • ‘sling:orderBefore = “otherChild”‘ — These influence how ‘/libs’ is combined with ‘/apps’.

      Post Comment