AEM in 40 Days
CalendarPhase 1 · Foundations

Day 3 of 40

The Java Content Repository

Everything in AEM is a node: /content, /apps, /libs, /conf

~35 min read1 video1 source page

By the end of today you should be able to

  1. Describe the JCR as a tree of nodes with typed properties
  2. Name the top-level paths and say what belongs in each
  3. Explain primary types and mixins, and recognise cq:Page vs nt:unstructured
  4. Read a page's node structure and predict where a component's dialog values are stored

One tree to rule them all

The Java Content Repository (JCR) is a specification — JSR-170, later JSR-283 — for storing hierarchical, semi-structured content. AEM's implementation is Apache Jackrabbit Oak. Practically, the repository is a single tree, a bit like a filesystem, except every node can also carry typed properties and every node has a type.

  • A node has a name, a primary type, optional mixin types, child nodes, and properties.
  • A property has a name and a typed value: String, Long, Double, Boolean, Date, Binary, Name, Path, or a multi-value array of those.
  • Paths look like /content/wknd/us/en/home/jcr:content/root/container/title.

This is why AEM feels different from a database-backed CMS. There is no "pages table". A page is a node, its content is child nodes, and a component's dialog values are properties on a node. Once that clicks, CRXDE Lite becomes the most useful debugging tool you have.

The top-level paths

  • /content — your site content, and /content/dam for assets. Mutable.
  • /apps — your project's code-side artefacts: components, templates types, clientlibs. Immutable at runtime on Cloud Service.
  • /libs — Adobe's product code. Never write here. To change product behaviour, overlay it under /apps.
  • /conf — editable templates, policies, and context-aware configuration. Mutable, authored.
  • /var — runtime data: audit logs, workflow instances, event data. Mutable, not for you to hand-edit.
  • /home — users and groups (/home/users, /home/groups).
  • /etc — legacy. Modern projects have largely emptied it; on Cloud Service most of what used to live here moved to /conf or /apps.
The rule that saves you

Never modify /libs. It is replaced wholesale on every product update, so your change vanishes and takes a day of debugging with it. Overlay under /apps with the same relative path instead.

Primary types and mixins

Every node has exactly one primary type, stored in the jcr:primaryType property. The ones you meet constantly:

  • cq:Page — a page. Almost empty itself; its real content lives in its jcr:content child.
  • nt:unstructured — the workhorse. Accepts any property and any child. Most component nodes are this.
  • sling:Folder / nt:folder — folders. sling:Folder allows arbitrary properties; nt:folder does not.
  • dam:Asset — a DAM asset, with renditions and metadata beneath it.
  • cq:Component, cq:Template, cq:ClientLibraryFolder — code-side node types under /apps.

A mixin adds capability to a node without changing its primary type — for example mix:versionable to allow versioning, or cq:LiveRelationship to mark a node as part of a live copy. They appear in the jcr:mixinTypes multi-value property.

Reading a page

A typical page from an archetype project looks roughly like this:

/content/wknd/us/en/home          [cq:Page]
  jcr:content                     [cq:PageContent]
    jcr:title = "Home"
    sling:resourceType = "wknd/components/page"
    cq:template = "/conf/wknd/settings/wcm/templates/page-content"
    root                          [nt:unstructured]
      container                   [nt:unstructured]
        title                     [nt:unstructured]
          sling:resourceType = "wknd/components/title"
          jcr:title = "Welcome"

Read that from the bottom up and you can see the whole model: the title node's jcr:title property is exactly what an author typed into that component's dialog. The sling:resourceType is what tells AEM which code renders it — which is tomorrow's topic.

Today's takeaway

Content, code and configuration all live in one typed tree. A dialog field is a property; a component instance is a node; sling:resourceType is the link between content and the code that renders it.

Watch

Adobe's own videos for this topic. They load only when you press play.

Introduction to JCR

Read on Experience League

The primary sources these notes are drawn from.

Your notes

Saved automatically to this browser.

Check yourself

11 questions on today's material. 80% to pass.

Take the quiz