Editable Templates, Policies and the Style System in AEM as a Cloud Service
If you learned AEM on CQ5 or early AEM 6.x, you probably built templates the old way: a cq:Template node under /apps, an allowedPaths regex, and a design dialog whose settings were stored in a design under /etc/designs. I wrote about that approach years ago in Create a Template in Adobe CQ5, and that post still gets a lot of readers.
On AEM as a Cloud Service (AEMaaCS) that approach hits a wall. /apps is immutable at runtime, so the design of a static template cannot be edited from the UI, and Adobe recommends editable templates instead. Editable templates, their structure and their content policies live in /conf, which is mutable content. Template authors change them in the Template Editor without a code deployment, and the Style System lets page authors pick a visual variation of a component without you building a new component for every look.
In this tutorial I will show how templates, policies and the Style System fit together, where each piece lives in the repository, and how to give your own component a Styles tab. Let’s see it step by step.

Table of contents
- Why this matters
- Who should read this
- Prerequisites
- Static templates in AEM 6.x vs editable templates in AEMaaCS
- Where templates and policies live in /conf
- Binding a site to its templates
- Template Editor: Structure, Initial Content and Layout
- Content policies
- The Style System
- Hands-on: build an Article Page template step by step
- Who owns templates on production?
- Which feature for which job
- Common mistakes and troubleshooting
- Hands-on challenge
- Key takeaways
- Knowledge check
- Frequently asked questions
- Continue your learning
- References
Why this matters
Adobe’s list of AEMaaCS changes is direct about static templates: “Static Template design information that is stored in /apps can’t be edited by way of the UI.” It recommends editable templates, and adds that if static templates are still required, “configuration information must come from Git”. So every design change on a static template becomes a code change and a full Cloud Manager pipeline run.
Editable templates fix three practical problems:
- Speed: template authors add an allowed component or change a default without waiting for a release.
- Fewer components: with the Style System one Teaser can have “Dark” and “Featured” variants instead of three copies of the same component.
- Clear roles: developers own template types, components and CSS; template authors own templates and policies; content authors own pages.
Who should read this
This post is for AEM developers moving a project from static templates and design mode to AEMaaCS, for architects who define how templates are governed across environments, and for template authors who want to understand what happens in the repository when they click around in the Template Editor.
Prerequisites
- A project generated from the AEM Project Archetype with
aemVersion=cloud. The examples use the app IDmysite. See AEM Project Archetype and Repository Structure for AEMaaCS. - A local AEM SDK author on
http://localhost:4502. See Set Up AEMaaCS Local Development. - Basic knowledge of Core Components and proxy components. See How to Use Core Components to Create Your AEM Website and Create Proxy Component in AEM.
- An account that can use the Template Editor. On the local SDK,
adminis fine.
Static templates in AEM 6.x vs editable templates in AEMaaCS
Before we touch the Template Editor, here is the difference in one table. Keep it in mind when you read old code in a migrated project.
| Aspect | Static template (AEM 6.x) | Editable template (AEMaaCS) |
|---|---|---|
| Location | /apps/<project>/templates | /conf/<site>/settings/wcm/templates |
| Who changes it | Developer, through a code deployment | Template author, in the Template Editor |
| Component settings | Design mode, stored in a design (/etc/designs) | Content policies under /conf/<site>/settings/wcm/policies |
| Allowed components | Design mode on the paragraph system | Policy of the Layout Container |
| Link to existing pages | Copied when the page is created | Structure changes are reflected on pages that use the template |
| Status on AEMaaCS | Design can’t be edited in the UI; configuration must come from Git | Recommended by Adobe |
Where templates and policies live in /conf
Everything for a site sits under one configuration folder. This is the layout Adobe documents, filled with what the archetype generates for mysite:
/conf/mysite (sling:Folder)
└── settings (sling:Folder)
└── wcm (cq:Page)
├── template-types (template types for this site)
│ ├── page
│ └── xf
├── templates (cq:Page)
│ ├── page-content (cq:Template, title "Content Page")
│ │ ├── jcr:content (status = enabled)
│ │ ├── structure (locked layout + cq:responsive breakpoints)
│ │ ├── initial (content copied into every new page)
│ │ ├── policies (which policy each component uses)
│ │ └── thumbnail.png
│ └── xf-web-variation (Experience Fragment template)
└── policies (cq:Page)
└── mysite/components/... (policies, grouped by component resource type)
A few details that matter in real projects:
- Template types are the blueprints that templates are created from. Adobe ships some in
/libs/settings/wcm/template-types(never change/libs); your own go in/conf/<site>/settings/wcm/template-typesor/apps/settings/wcm/template-types. - status on the template’s
jcr:contentisdraft,enabledordisabled. Authors can only create pages from enabled templates. - policies inside a template does not hold design values. It holds references, for example
policies/jcr:content/root@cq:policy, which points to the policy of the page’s root container. - Lookup order: template types and policies are resolved from the current folder, then parent folders, then
/conf/global, then/apps, then/libs. If the same entry exists in two places, the one closest to the current folder wins.
Binding a site to its templates
Two properties connect a site to its configuration folder and decide which templates authors see in the Create Page wizard.
1. The configuration folder and cq:conf
For a new site, create the folder under Tools > General > Configuration Browser > Create and tick Editable Templates. Be careful: Adobe notes that you cannot unselect a feature once the configuration has been created. The archetype already creates /conf/mysite with templates and policies, so you only need the Configuration Browser for additional folders.
The site is bound to that folder with cq:conf on the jcr:content node of the site root. The archetype writes this for you, together with the allowed templates rule:
<!-- ui.content/src/main/content/jcr_root/content/mysite/.content.xml (excerpt) -->
<jcr:content
jcr:primaryType="cq:PageContent"
cq:conf="/conf/mysite"
sling:configRef="/conf/mysite"
cq:allowedTemplates="[/conf/mysite/settings/wcm/templates/(?!xf-).*]"/>
2. Allowed templates
AEM uses the first non-empty cq:allowedTemplates property it finds while walking up the page tree. Templates can also carry allowedPaths, allowedParents and allowedChildren, but Adobe recommends using only cq:allowedTemplates, and only on the site root. The regex above allows every template in /conf/mysite except the Experience Fragment ones, which start with xf-. Authors can change the list in the Advanced tab of Page Properties.
Note:- Do not enable editable templates on
/conf/globaljust because it is quicker. Adobe calls it not recommended. Keep one configuration folder per site or brand, so a template change for one site cannot surprise another.
Template Editor: Structure, Initial Content and Layout
Open a template from Tools > General > Templates. The editor has three modes, and each one writes to a different node of the template:
- Structure writes to
structure. Components added here appear on every page and cannot be changed by page authors. If you unlock a component (usually a container), AEM setseditable=trueon it and page authors can add content inside it. Policies are assigned in this mode. - Initial Content writes to
initial. This is the starting content of a new page, which authors can change or delete. Policies are never defined in this mode. - Layout sets the responsive layout of components per breakpoint.
The big win compared to static templates: changes to the structure are reflected on the pages already created from the template. Initial content is only copied when a page is created, so changing it later affects new pages only.
Content policies
A content policy is a reusable piece of design configuration: which components a container allows, which heading sizes a Title offers, which styles a Teaser has. A policy is stored once under /conf/<site>/settings/wcm/policies and can be referenced by many templates. There are two kinds you will use every day:
- Page policy: opened from Page Information > Page Policy in the Template Editor. With the Core Components Page v3 component this is where the page client libraries are set.
- Component policy: set on a component in Structure mode. A policy is mandatory for container components. The Layout Container policy has the tabs Allowed Components, Default Components and Responsive Settings.
For the Page v3 component, the page policy dialog maps to these properties:
| Field in the page policy | Property | Archetype value |
|---|---|---|
| Client Libraries | clientlibs | mysite.dependencies, mysite.site |
| Client Libraries JavaScript Page Head | clientlibsJsHead | mysite.dependencies |
| Load JavaScript Libraries asynchronously | clientlibsAsync | not set |
| Web Resources Client Library | appResourcesClientlib | not set |
Note:- Policies are shared. If two templates point to the same Layout Container policy and you add a component to it, both templates get the component. When a template needs different rules, create a new policy for it instead of editing the shared one.
The Style System
The Style System lets a template author define named styles in a component policy, and a page author pick them from the paintbrush icon in the component toolbar. Each style is just one or more CSS classes. In the policy dialog you work with four fields: Group Name, Style Name, CSS Classes and Styles can be combined, which allows several styles of the same group to be selected at once.
Behind the dialog the policy stores the styles like this (the property names come from the StyleConstants class in the AEM SDK):
<!-- /conf/mysite/settings/wcm/policies/mysite/components/teaser/policy_teaser_card -->
<policy_teaser_card
jcr:primaryType="nt:unstructured"
jcr:title="Teaser - Card"
sling:resourceType="wcm/core/components/policy/policy">
<jcr:content jcr:primaryType="nt:unstructured"/>
<cq:styleGroups jcr:primaryType="nt:unstructured">
<item0
jcr:primaryType="nt:unstructured"
cq:styleGroupLabel="Theme"
cq:styleGroupMultiple="{Boolean}false">
<cq:styles jcr:primaryType="nt:unstructured">
<item0
jcr:primaryType="nt:unstructured"
cq:styleId="1731200000001"
cq:styleLabel="Dark"
cq:styleClasses="cmp-teaser--dark"/>
<item1
jcr:primaryType="nt:unstructured"
cq:styleId="1731200000002"
cq:styleLabel="Featured"
cq:styleClasses="cmp-teaser--featured"/>
</cq:styles>
</item0>
</cq:styleGroups>
</policy_teaser_card>
When an author applies a style, the component node stores the selected IDs in cq:styleIds, not the class names. That is why you should keep cq:styleId values unique and stable: you can later change the CSS class of a style in the policy, and every page that uses it picks up the new class.
Where the class ends up in the HTML
Adobe’s documentation says the style class “is inserted on the decoration wrapper element of the component”. The wrapper is the element AEM puts around your component’s own markup. Rendered on a page it looks roughly like this (layout grid classes left out):
<div class="teaser cmp-teaser--dark">
<div class="cmp-teaser">
<!-- the component's own markup -->
</div>
</div>
So write your CSS against the wrapper class and the component’s own block class, and ship it in a client library that the page policy loads:
/* style classes sit on the wrapper, the BEM block sits inside it */
.cmp-teaser--dark .cmp-teaser {
background: #1f2937;
color: #ffffff;
}
.cmp-teaser--featured .cmp-teaser__title {
font-size: 2rem;
}
Two more rules from the documentation are worth knowing. You can let a style change the wrapper element by listing allowed names in cq:styleElements on the component, for example [div,section,span], but Adobe advises not to set element names for styles that can be combined. And the Style System “only applies to pages created with the Page Editor”.
Hands-on: build an Article Page template step by step
We will create an Article Page template for mysite, limit its components, give the Teaser two styles, and add a Styles tab to a custom component. Start your local SDK and deploy the project once with mvn clean install -PautoInstallSinglePackage.
Step 1 : Check what the archetype created
Open CRXDE Lite at http://localhost:4502/crx/de and look at three places:
/conf/mysite/settings/wcm/templates/page-content: the Content Page template. Check thatjcr:content@statusisenabled./conf/mysite/settings/wcm/policies: the page policy and the container policies./content/mysite/jcr:content:cq:confandcq:allowedTemplates, as shown earlier.
Step 2 : Create the template
Go to Tools > General > Templates, open the MySite folder and click Create. Select the Page template type, click Next, enter the title Article Page and a short description, then click Create and Open. The new template is created in draft status.
Step 3 : Define the structure
In Structure mode, keep everything that every article shares locked, such as the header and footer Experience Fragments. Select the main container and click the lock icon to unlock it. From now on page authors can add components inside that container, and nothing else on the page.

Step 4 : Limit the allowed components
Select the unlocked container and click the policy icon. Create a new policy called Article - Main. On the Allowed Components tab, open the MySite – Content group and tick only Title, Text, Image, Teaser and List. Click Done. I always create a new policy here; reusing the archetype’s container policy would also change the Content Page template.

Step 5 : Add initial content
Switch to Initial Content mode. Add a Title and a Text component to the unlocked container with placeholder text such as “Write the article summary here”. Every new article starts with these two components, and authors can change or remove them.
Step 6 : Check the page policy and enable the template
Open Page Information > Page Policy and select the existing page policy, so the template loads mysite.dependencies and mysite.site like the rest of the site. Then go back to the Templates console, select Article Page and click Enable. Because its name does not start with xf-, the site root regex already allows it.

Step 7 : Add Style System styles to the Teaser
Back in the template, in Structure mode, select a Teaser inside the container (add one temporarily if needed) and open its policy. Create a policy Teaser - Card. On the Styles tab add a group Theme with the styles Dark (cmp-teaser--dark) and Featured (cmp-teaser--featured). Leave “Styles can be combined” unticked, because a teaser should not be dark and featured at the same time. Add the CSS from the previous section to your ui.frontend styles and redeploy.
Now create a page from Article Page, add a Teaser, and pick Dark from the paintbrush icon. In CRXDE you will see cq:styleIds on the teaser node.

Step 8 : Give a custom component a Styles tab
Core Components from v2 onwards need no extra configuration for the Style System. Your own components do: they need a design dialog that includes Adobe’s style tab. For a custom hero component create _cq_design_dialog/.content.xml next to the component definition:
<?xml version="1.0" encoding="UTF-8"?>
<!-- ui.apps/src/main/content/jcr_root/apps/mysite/components/hero/_cq_design_dialog/.content.xml -->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Hero"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<styletab
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/include"
path="/mnt/overlay/cq/gui/components/authoring/dialog/style/tab_design/styletab"/>
</items>
</tabs>
</items>
</content>
</jcr:root>
Deploy, open the policy of the hero component in the Template Editor, and the Styles tab is there. If you are building that component from scratch, the companion post Build a Custom Component in AEM as a Cloud Service walks through the HTL, Sling Model and edit dialog.
Step 9 : Put the template and policies into Git
What you built lives only in your local repository. Adobe’s WKND tutorial recommends to “persist configurations, like templates and related content policies, to source control”. Pull /conf/mysite/settings/wcm/templates/article-page and the new policies into ui.content with the AEM sync feature of your IDE or the repo tool, then commit.
Now look at the archetype’s ui.content filter:
<!-- ui.content/src/main/content/META-INF/vault/filter.xml (excerpt) -->
<filter root="/conf/mysite" mode="merge"/>
merge means existing content is not modified; only new content is added. That is exactly what you want for templates that authors edit on the environment, but it has a side effect that catches every team once: if you change a template in Git after it was first deployed, the change does not reach environments where the template already exists.
Who owns templates on production?
Adobe gives you the building blocks but no single rule here. What the documentation does say: content packages deploy to all environment types, content that is specific to one environment must be installed manually with Package Manager, and there is no mechanism to roll back mutable content package changes. From my experience, decide on one source of truth per site and write it down:
- Git owns template types, components, CSS and the first version of each template and policy. New templates reach every environment through the pipeline.
- Template authors own changes to existing templates and policies on production. If a lower environment needs the same change, copy it down with a content package, not the other way round.
- Keep the number of templates small. Adobe’s templates guide suggests staying under 100; in practice a site rarely needs more than ten.
Personally I prefer this split, because it never asks a developer to overwrite something an author changed on production last week.
Which feature for which job
| You want to… | Use | Stored in |
|---|---|---|
| Fix a header and footer on every page | Locked components in Structure mode | Template structure |
| Control which components authors can add | Layout Container policy, Allowed Components | /conf/…/policies |
| Pre-fill new pages | Initial Content mode | Template initial |
| Load site CSS and JS | Page policy (client libraries) | /conf/…/policies |
| Offer visual variants of a component | Style System styles in the component policy | cq:styleGroups in the policy, cq:styleIds on the content |
| Limit templates per site | cq:allowedTemplates on the site root | /content/<site>/jcr:content |
Common mistakes and troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The template is not offered in the Create Page wizard | Template still in draft, or the cq:allowedTemplates regex does not match its path | Enable the template; check the regex on the site root |
| No templates at all for a new site | cq:conf missing on the site root jcr:content | Set cq:conf to the configuration folder |
| A component is missing from the side panel | It is not allowed in the Layout Container policy, or its componentGroup starts with a dot (hidden) | Allow it in the policy; use a visible group |
| No Styles tab on a custom component | No _cq_design_dialog with the style tab include | Add the design dialog from Step 8 |
| A style is selected but nothing changes | CSS not in a client library loaded by the page policy, or the selector targets the inner element only | Load the clientlib; write .cmp-x--style .cmp-x |
| A template change in Git never reaches Stage | mode="merge" on /conf/mysite | Change it in the Template Editor on the environment or install a content package |
| Editing one policy changed several templates | The policy is shared | Create a separate policy for the template that needs different rules |
Hands-on challenge
Create a Landing Page template that allows only Teaser, Title and Button in its main container. Add a style group Spacing to the Teaser with two combinable styles, Large top margin and Large bottom margin. Apply both on a page and confirm in CRXDE that the teaser node stores two IDs in cq:styleIds. Success means the Article Page template still offers its original components, because you created new policies instead of editing shared ones.
Key takeaways
- Static template designs can’t be edited in the UI on AEMaaCS; Adobe recommends editable templates.
- Templates, template types and policies live under
/conf/<site>/settings/wcm, which is mutable content. - Bind the site with
cq:confand control templates withcq:allowedTemplateson the site root only. - Structure changes reach existing pages; initial content only affects new pages.
- The Style System adds CSS classes to the component wrapper; custom components need the style tab in a design dialog.
- The archetype deploys
/confin merge mode, so decide who owns template changes after the first deployment.
Knowledge check
1. Where does AEMaaCS store the policies of the site mysite?
Under /conf/mysite/settings/wcm/policies, grouped by component resource type.
2. A template author changes a locked header in Structure mode. Which pages show the change?
All pages created from that template, including existing ones, because structure is dynamically linked.
3. What does a page store when an author applies a style?
The IDs of the selected styles, in cq:styleIds on the component node.
4. Which property should you use to limit templates per site, and where?
cq:allowedTemplates, only on the site root, as Adobe recommends.
5. Why does a template change committed to Git not appear on an environment where the template already exists?
The archetype’s ui.content filter uses mode="merge" for /conf/mysite, so existing nodes are not overwritten.
Frequently asked questions
Can I still use static templates on AEM as a Cloud Service?
Existing static templates can still render pages, but their design can’t be edited in the UI and the configuration must come from Git. Adobe recommends moving to editable templates.
What is the difference between site templates and page templates?
Adobe says site templates “should not be confused with page templates”. A site template defines the overall structure of a new site and is used for quick site creation; a page template (editable template) defines the structure and initial content of one page.
Do Core Components need anything extra for the Style System?
No. Core Components v2 and later need no additional configuration. Only your own components need the style tab in a design dialog.
Can I move templates between environments with Package Manager?
Yes, /conf is mutable, so content packages with templates and policies can be installed. Remember that there is no rollback for mutable content, so take a backup package first.
Should I put templates in /conf/global so every site can use them?
Adobe calls enabling editable templates on the global folder not recommended. Use one folder per site or brand, and share only what really is common.
Continue your learning
- Next: Build a Custom Component in AEM as a Cloud Service: HTL, Sling Model and Touch UI Dialog.
- Core Components: How to Use Core Components to Create Your AEM Website.
- Client libraries: Explore Client Libraries in AEM.
- The old way, for comparison: Create a Template in Adobe CQ5 and Create Design Dialog in AEM.
- Practice quiz: AEM Sites (components and templates) quiz.
- Roadmap: AEM as a Cloud Service learning path.
References
- Page Templates (AEMaaCS developer documentation)
- Creating Page Templates (Template Editor)
- Style System
- Configurations and the Configuration Browser
- Notable Changes to AEM as a Cloud Service
- Deploying to AEM as a Cloud Service
- WKND tutorial: Pages and Templates
- Site Templates
- AEM Project Archetype on GitHub
- Core Components Page v3
Leave a Reply