Skip to content
Switch branches/tags
This branch is 58 commits ahead of labertasch/sightlytodomvc:master.

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

HTL TodoMVC Example

This example shows how to build components in AEM 6+ with HTL. It's a feature-complete implementation of the famous TodoMVC exercise, which is traditionally meant for client-side JavaScript frameworks. This implementation though shows how such an application can easily be built in AEM and it's status persisted on the server using the Apache Sling REST framework.

All in about 300 lines of server- and client-side JavaScript code, following the latest AEM best practice!

Learning HTL

The HTML Template Language (HTL), formerly known as Sightly, has been introduced with Adobe Experience Manager 6.0 and takes the place of JSP (JavaServer Pages) as the preferred and recommended server-side template system for HTML.

The HTML Template Language documentation on the AEM Site is a great resource for getting started.

You can also read following blog posts:

Get help from other HTL users:

If you are interested to learn how we came up with HTL, check out the Behind the Scenes Youtube channel.


The server sets a number of data attributes to the HTML elements that are interactive. These data attributes are instructing the app front-end about the asynchronous POST requests that are to be done when interacting with these elements, in order to persist the manipulations to the server. After each manipulation, the app content is reloaded through an asynchronous query to retreive the HTML fragment of the view that must be updated.

Beyond the classic MVC, this architecture also has following particularities:

  • The Sling Post Servlet makes it possible that no code has to be written to handle the POST requests.
  • Through the data attributes set by the server, the client needs no knowledge of how to structure the data for the Sling Post Servlet.
  • To retreive the HTML fragment of what must be updated on the page, a simple todoapp selector allows to trigger the specific template that handles that part of the view.
  • The filters (to show all, or only active or completed items) use an additional selector, which allows the server to know which items to render.

Note that Java could also have been used instead of the server-side JavaScript files.


The nodes located in the content repository at /content/todo are serialized in a .content.xml file with following content:

  • jcr:content The content node for the todo page. It contains the title and various labels that are to be displayed on the page, but important is the sling:resourceType property, which makes this node rendered by the page component.
    • The child nodes with their titles and completed status. As the sling:resourceType property defines it, they are rendered by the item component.

Server-side components

AEM components render individual content nodes based on their sling:resourceType properties.

  • page Renders the page content node.
    • page.html Entry point: The outer page markup that doesn't change when actions are performed.
    • page.js Server-side script that prepares additional data model needed by page.html.
    • todoapp.html Renders the list of todo items. Called directly when fetching what changed in the view.
    • todoapp.js Server-side script that prepares additional data model needed by the template, which also defines the data attributes that instruct the front-end POST requests.
  • item Renders the todo item content nodes.
    • item.html Renders the markup for the items.
    • item.js Server-side script that prepares additional data model needed by the template, which also defines the data attributes that instruct the front-end POST requests.
  • utils Collection of reusable scripts.
    • filters.js Defines what filters are set depending on the request selectors (i.e. to show all, or only active or completed items).

Client-side libraries

Client libraries can conveniently combine and minimize multiple CSS and JS files:

Running it

  • Create package
    • Get the code from this Git repository, for e.g. with following command line:
      git clone
    • Create a ZIP file from the src folder, for e.g. in a Unix shell you can do:
      cd aem-sample-sightly-todomvc/src
      zip -r jcr_root META-INF
  • Start AEM
    • Double-click on the AEM JAR to start an instance if you haven't done that already.
    • Once you're prompted with a login in your browser, enter admin as username and password.
  • Install package
    • Goto the AEM Package Manager.
    • Click on Upload package and browse for your ZIP file, then hit OK.
    • Once shows up at the top of the list, click on Install => Install.
  • Run the app
    • Access the Todo page.


Adobe Experience Manager code example of a simple web application







No releases published


No packages published