AEM Sites Developer Expert cheat sheet
AEM Sites Developer Expert · Keep the key ideas within reach.
AEM Sites Architecture and Component Development
AEM runs on Apache Felix (OSGi), Apache Jackrabbit Oak (JCR), and Sling; requests resolve resource → resource type → sling:resourceSuperType chain → script.
Component definition node uses sling:resourceType plus jcr:title and componentGroup; the componentGroup value determines the group shown in the Components browser.
sling:resourceSuperType enables inheritance so a child component can override only the scripts or dialog fields it needs.
Proxy components have no logic of their own; they set sling:resourceSuperType to the core component and are the recommended pattern for editable templates.
Core Components ship with versioned clientlibs and policy-driven design; extending them via proxy avoids patching product code.
OSGi configs live under /apps//config, /config.; runmode-specific nodes override the default node values.
AEM as a Cloud Service disallows mutable /libs and /apps at runtime, so custom code must be deployed via Cloud Manager pipelines.
Component dialog fields persist to the component node's properties; names must match the Sling Model field or getter mapping.
Templates, Policies, and Editable Templates
Editable templates are stored under /conf//settings/wcm/templates and consist of structure, initial content, and policies nodes.
The template type (template author) restricts which components can be added; policies on the template restrict what a page author can change.
Policies are stored under /conf//settings/wcm/policies and referenced by policy mappings on the template.
Static templates (/apps/.../templates) are legacy and cannot be edited by authors; editable templates are required for the Layout Container and responsive grid.
The structure node holds locked components (such as header/footer); initial content is copied into each new page at creation time.
A template's allowedPaths and the page's cq:allowedTemplates control which templates can be used for a page.
Policy-driven design replaces the legacy design mode; Design mode in editable templates edits policies, not cq:design nodes.
Page properties dialog is defined by the page component's dialog; template settings can hide or lock fields.
Sling Models, HTL, and Client-Side Libraries
@Model(adaptables = {Resource.class, SlingHttpServletRequest.class}) declares a model; @Model(adapters = ...) exposes it as an adapter target.
@Inject, @ValueMapValue, @ChildResource, and @OSGiService inject values; @Via supports indirect adaptation through an intermediate object.
@Default supplies a fallback when injection fails; @Optional prevents a missing injection from failing the model (default injection strategy is REQUIRED).
HTL expressions use ${...}; data-sly-use adapts a model, data-sly-list iterates, data-sly-test conditionally renders, and data-sly-resource includes a resource.
HTL auto-escapes by context; use the @ context option (e.g., ${model.text @ context='html'}) to control escaping explicitly.
Clientlibs are defined with categories, dependencies, and embed; the cq:ClientLibraryFolder node holds js.txt and css.txt entry files.
Clientlib inclusion uses data-sly-call with the clientlib template, or the cq:includeClientLib tag in JSP; categories are comma-separated.
The HTL Use-API allows Java models or JS use-api scripts; the model is referenced in HTL via ${modelName.property}.
Content Authoring, Dialogs, and Component Configuration
Granite UI dialogs are built from field resource types (e.g., granite/ui/components/coral/foundation/form/textfield) with name, label, and value properties.
Multifield uses granite/ui/components/coral/foundation/form/multifield wrapping a field; each entry stores as a child node or JSON array depending on config.
cq:dialog (Touch UI) is the modern dialog; dialog (Classic) is legacy and should not be used for new components.
The dialog's field name maps to the JCR property; nested names with ./ or relative paths write to child nodes.
Design/policy dialog (cq:design_dialog) holds author-configurable settings surfaced through the policy.
The Content Fragment editor and CF Models (under /conf) define structured content; CFs are referenced by components and delivered via the Assets API.
Experience Fragments are page-like assets reusable across channels; they are built from editable templates and exported to Target/Adobe Experience Cloud.
cq:EditConfig controls in-place editing behavior, listeners, and actions (e.g., cq:actions, cq:emptyText, cq:dropTargets).
Workflows, Replication, and Content Activation
Replication agents (author → publish) are configured under /etc/replication/agents.author; the default agent is publish.
Activation is triggered by the Activate action; Deactivate removes content from publish; both go through the replication queue.
Workflow models are authored in the Workflow Editor and stored under /conf or /etc/workflow/models; steps run as participants or automated process steps.
The AEM Workflow Engine uses a launcher (cq:WorkflowLauncher) to start workflows on content events such as node creation or modification.
The Request for Activation workflow (DAM update asset, etc.) routes content to approvers before replication.
Workflow inbox (/aem/inbox) holds tasks assigned to users/groups; participants can complete, delegate, or step back.
Replication is asynchronous; the replication queue can be monitored at /etc/replication/agents.author and via the Replication Queue UI.
The 'Publish' action on a page tree replicates the page and its referenced assets when the tree activation option is used.
Dispatcher, Caching, and Performance
Dispatcher sits in front of publish and serves cached content from its cache directory; it forwards uncached requests to the publish instance.
The dispatcher.any config defines /cache, /rules, /filter, /renders, and /statistics; /filter controls which URL patterns are allowed.
Cache invalidation is triggered by replication flush agents (Dispatcher Flush) that call the dispatcher's invalidate endpoint.
The /statistics section enables the dispatcher status page for cache hit/miss metrics.
Cache headers (Cache-Control, Surrogate-Control, and the dispatcher TTL) determine cache lifetime; ACS Commons or custom headers control TTL.
The /filter section uses allow/deny glob patterns; overly permissive filters expose internal paths and are a common security finding.
Sticky sessions or session affinity are required for author; publish is typically stateless and should not cache authenticated responses.
Performance tuning includes enabling gzip, minimizing clientlibs, using the dispatcher for static assets, and avoiding uncached component calls.
Multi-Site Management, Localization, and Translation
MSM uses blueprints and live copies; a live copy inherits content from a blueprint and synchronizes via rollout configurations.
Rollout configs define which properties/child nodes sync from blueprint to live copy; the default is the standard rollout config.
Live relationships are stored as cq:LiveSyncConfig and cq:LiveSync nodes; breaking inheritance creates a local override.
Language copies are created via the Language Copy feature; the source is the language master and the target is the translated locale.
The Translation Integration Framework (TIF) connects to translation providers (e.g., Microsoft, custom connectors) via cloud services.
Translation projects are created from the References panel or the Language Copy wizard and track translation status per page/asset.
The i18n dictionary (/content/dam or /apps i18n) supports UI string translation via the i18n HTL object.
The Language Navigation component lists language copies based on the page's language structure and the jcr:language property.
Security, Permissions, and User/Group Management
AEM security is built on Jackrabbit Oak; permissions are granted via ACLs on paths, evaluated by principal (user/group).
The permission set includes jcr:read, jcr:write, jcr:all, and AEM-specific permissions such as crx:replicate and replicate.
Users should be members of groups; permissions are assigned to groups, not individual users, for maintainability.
The 'everyone' group is special: any permission granted to it applies to all users, including anonymous.
The author and publish instances have separate user stores; replication of users is not automatic and must be handled deliberately.
The admin session bypasses ACL checks; production code must use a service user (rep:serviceUser) with least privilege.
The Package Manager and CRX/DE are high-risk tools; restrict their use and audit access.
Sling Authentication and the Authentication Handler chain control login; SAML/OAuth integrations replace the default login module.