Using Accelerated Mobile Pages (AMP) in Jahia

November 14, 2023

Accelerated Mobile Pages (AMP) is an open source project supported by Google to improve mobile phone web browsing. Simply put, it's an HTML page with dedicated scripts and tags.

Currently AMP technology is mostly used to display news and articles, content that are read on a cellular phone and that needs to be loaded fast. This kind of content match well with Jahia “content templates” approach.

We describe here how to integrate AMP technology with a simple example that creates AMP pages to display content element of a news type based on the Digitall demo site. This example can be transposed easily to any other kind of content


To understand and reproduce this example, you need to run an instance of Jahia that contains the sample Digitall site.

Creating AMP content templates

As any other content rendering in Jahia, a dedicated AMP view needs to be created for the news. It can be done either with adding it to the template set or creating a dedicated module for it. To ease this example, we have created a sample module that can be found here:

Compile and deploy it to your Jahia instance.

mvn clean install



Creating the content template

The goal is to have an AMP content template for news, other type of content may need to get several content templates. First, create a template folder for the news where you will put the AMP content template. This will help to use the same template name for all the AMP content templates.

First, add a dependency to the news module


Next create a template, and a content template for the news content type:



Uncheck "Automatically synchronize name with title:"

Set the same to : amp


If you encounter any issue in this phase, please check out the result here:

Creating views

AMP needs a dedicated structure for its page. You can find more information on it here:

In Jahia, it means to create views. First, create the template view, then the view of the news nodetype.

Template view

From the Jahia studio, select the file system tab, and right click on the root folder, select Add view


In the selector, type "template" then pick Template. Choose Template as a parent type of "Content template" and pageTemplate.

Copy the content from and save the view naming it: amp-sample



The view is now available in the file system tab:


Create an area name pagecontent in this view to be able to create content.

To do so, replace the inner <body> section to a Jahia area tag that defines a pagecontent area that displays the main resource:

<template:area editable="true" moduleType="existingNode" view="detail-amp"/>

This is the equivalent of creating a standard area, and drag and drop a main resource area component in it, setting the view to detail-amp.

News nodetype view

As for template, create a new view from the news nodetype but this time, copy the content from the detail view of the news that you can get here:

Create the view as done for the template but selecting "News Entry" instead of template in the nodetypes list, copy the detail view content of the new in it, then save it naming it detail-amp.

You should get the following result:


After copying the detail view of the news from github, remove the following lines from the code of your view:

<%@ taglib prefix="bootstrap" uri="" %>

Now the views are set, compile and deploy your module to get the view working

Click on "compile and deploy", the first icon in the file system tab.


Setting the content template view

Now assign the views to the previously created template. Edit the news content template to set the view to amp-sample.


Everything is almost set. Let's compile the module once again, and enable it on the Digitall Demo site.

Click on module detail in the top bar, then enable the module on Digitall Demo site.


If you encounter any trouble to get it work, you can get the source code of this step here:

Cleaning up the view

Now exists an AMP view for our news. But this view must be clean up to match the AMP constraints. You can find more detail on the AMP format here:

To summarize, no external javascript or css are allowed except the ones provided by AMP, so the view needs to be cleaned to only keep what is allowed by AMP.

Assuming Jahia is installed in root context with an Digitall imported site, the relevant URL displaying a news is:



And the AMP view of the news: http://localhost:8080/cms/render/default/en/sites/digitall/home/newsroom/news-entry/article/movies-can-determine-your-succes.amp.html


Validating the AMP view

This validation can be done using the debugging tools of AMP to debug as described here:

In this case, enable the validation activating Chrome dev tools and using the URL

http://localhost:8080/jahia/cms/render/default/en/sites/digitall/home/newsroom/news-entry/article/movies-can-determine-your-succes.amp.html#development=1 to get the following result:


As displayed, there are 2 errors that need to get fixed to validate the AMP page. An AMP page must be valid to be served by a cache.

Removing StaticAssetFilter unwanted output

The first error is due to the StaticAssetFilter that manage the resources that the modules can provide. As AMP does not support external resource, the entries added by this filter must be removed. There are 2 possibilities:

  • disabling the filter and override it to define a custom filter that not do the import.
  • Create a custom filter that remove unwanted entries.

In this example, only the 2nd filter is described.

Creating a newJahia Render Filter

Add a java class named AssetsAMPFilter in the package org.jahia.modules.digitall.filters

A default Filter contains

package org.jahia.modules.digitall.filters;

* Render Filter that cleans up the StaticAssetFilter for AMP rendering
public class AssetsAMPFilter extends AbstractFilter{
   public String execute(String previousOut, RenderContext renderContext, Resource resource, RenderChain chain) throws Exception {
       return super.execute(previousOut, renderContext, resource, chain);

The bean declaration in the spring module file must be set (you have to remove the disabled extension)


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""
   <bean id="cleanUpAssetsAMPFilter" class="org.jahia.modules.digitall.filters.AssetsAMPFilter">
   <property name="priority" value="-1"/>
   <property name="applyOnEditMode" value="false"/>
   <property name="applyOnConfigurations" value="page"/>
   <property name="applyOnNodeTypes" value="jnt:news, jnt:article"/>

Values explanation:

  • priority: The StaticAssetFilter must be changed, this operation must be performed after its execution, meaning that the filter must be before it, less than 0)
  • applyOnEditMode: Due to its constraints, the AMP view is not working in edit mode.
  • applyOnConfigurations: Set to page, as the StaticAssetFilter.
  • applyOnNodeTypes: The applied filter is restricted to the news only.

Excluding unwanted content

<script type="text/javascript">
var contextJsParameters={contextPath:"/jahia",lang:"en",uilang:"en",siteUuid:"40ef8fce-72e8-41ec-9d93-32a2fe9807ef",wcag:true,ckeCfg:""}; var CKEDITOR_BASEPATH="/jahia/modules/ckeditor/javascript/"; var scayt_custom_params=new Array(); scayt_custom_params['sLang']='en_US';

Using the following code in the AssetsAMPFilter removes it:

private final static String MARKER = "macro LineToRemove not found";
public String execute(String previousOut, RenderContext renderContext, Resource resource, RenderChain chain) throws Exception {
   String out = super.execute(previousOut, renderContext, resource, chain);

   // Remove unsuported scripts and link lines added by the staticAssetFilter
   if (StringUtils.equals(resource.getTemplate(), "amp")) {
       String[] lines = out.split(System.getProperty("line.separator"));
       for (int i = 0; i < lines.length; i++) {
           if (StringUtils.contains(lines[i], "contextJsParameters")) {
               lines[i] = lines[i - 1] = lines[i + 1] = MARKER;
           } else if (StringUtils.contains(lines[i], "<link id=\"staticAssetCSS")) {
               lines[i] = MARKER;
       StringBuilder result = new StringBuilder();
       for (String s : lines) {
           if (!StringUtils.equals(s, MARKER)) {
       out =  result.toString();

   return out;

Once compiled and deploy, only one error remains in AMP validation


If you encounter any difficulties to get to that point, check-out the source code from here:

Fixing the news view

The remaining error is due to the image tag that is not supported by AMP as described here:

The news view needs to be updated to fit the AMP usage, changing the <img> tag to <amp-img>

<figure><img src="<c:url value="${image.node.url}" context="/"/>" alt="${image.node.displayableName}"></figure>


<c:set var="width" value="${['j:width'].long}"/>
<c:set var="height" value="${['j:height'].long}"/>
<figure><amp-img src="<c:url value="${image.node.url}" context="/"/>" width="${width}" height="${height}">
       <img src="<c:url value="${image.node.url}" context="/"/>" alt="${image.node.displayableName}">


Code cleanup can also be performed to remove unsupported tag like <template:addResource/>

Now the page is validated.

If you get any trouble to get to that point, you can download the source of this step here:

Header links

To be discoverable, a page must declare that an AMP version is available. Add this information in the html version of the amp page. A link to the html version can be set in the AMP page.

For this, adopt the previously used filter. Depending of the context, the corresponding link will be added in the header section.

Editing the filter

String out = super.execute(previousOut, renderContext, resource, chain);
// Build the amp links that will be used in the header
URLGenerator url = renderContext.getURLGenerator();
String resourceUrl = url.getServer() + url.getContext() + url.getBase() + resource.getNode().getPath();
String ampLink = "<link rel=\"ampType\" href=\"" + resourceUrl + "TEMPLATE.html\" />";

// Remove unsuported scripts and link lines added by the staticAssetFilter
if (StringUtils.equals(resource.getTemplate(), "amp")) {
   String[] lines = out.split(System.getProperty("line.separator"));
   for (int i = 0; i < lines.length; i++) {
       if (StringUtils.contains(lines[i], "contextJsParameters")) {
           lines[i] = lines[i - 1] = lines[i + 1] = MARKER;
       } else if (StringUtils.contains(lines[i], "<link id=\"staticAssetCSS")) {
           lines[i] = MARKER;
   StringBuilder result = new StringBuilder();
   for (String s : lines) {
       if (!StringUtils.equals(s, MARKER)) {
   out =  result.toString();
   // Set the values for AMP Link
   ampLink = StringUtils.replace(ampLink, "ampType", "canonical");
   ampLink = StringUtils.replace(ampLink, "TEMPLATE", "");
} else {
   // Set the values for AMP Link
   ampLink = StringUtils.replace(ampLink, "ampType", "amphtml");
   ampLink = StringUtils.replace(ampLink, "TEMPLATE", ".amp");
// Add amp link
out = StringUtils.replace(out, "</head>", ampLink + "\n</head>");
return out;

Removing the hardcoded link

In the header section of template.amp-sample.jsp is a hard-coded link from the example that has to be removed

<link rel="canonical" href="" />

Compiling and testing

Once compiled, go to the html page to see in the header section the following link:

<link rel="amphtml" href="http://localhost:8080/cms/render/default/en/sites/digitall/home/newsroom/news-entry/article/movies-can-determine-your-succes.amp.html" />

And in the AMP page this one:

<link rel="canonical" href="http://localhost:8080/cms/render/default/en/sites/digitall/home/newsroom/news-entry/article/movies-can-determine-your-succes.html" />

If you get any trouble to get this result, you can get the source code from:

Making it nicer

Creating custom styles

It is possible to declare custom style. This has to be done in the header section of the page, using the amp-custom style attribute.

<style amp-custom>
 .btn-primary {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #6600cc;
   background-image: -moz-linear-gradient(top, #6600cc, #6600cc);
   background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#6600cc), to(#6600cc));
   background-image: -webkit-linear-gradient(top, #6600cc, #6600cc);
   background-image: -o-linear-gradient(top, #6600cc, #6600cc);
   background-image: linear-gradient(to bottom, #6600cc, #6600cc);
   background-repeat: repeat-x;
   filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6600cc', endColorstr='#ff6600cc', GradientType=0);
   border-color: #6600cc #6600cc #400080;
   border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
   color: #ffffff;
 .btn {
   display: inline-block;
   padding: 4px 12px;
   margin-bottom: 10px;
   font-size: 14px;
   font-weight: bold;
   line-height: 20px;
   text-align: center;
   vertical-align: middle;
   cursor: pointer;
   background-color: #ffffff;
   border: 1px solid #cccccc;
   border-bottom-color: #b3b3b3;
   -webkit-border-radius: 4px;
   -moz-border-radius: 4px;
   border-radius: 4px;
   text-shadow: 0 1px rgba(0, 0, 0, 0.1);

Adding AMP scripts

Amp scripts can be added to enhance the rendering of the news. For example, using  amp-fit-text.

First add in the header section of the template:

<script async custom-element="amp-fit-text" src=""></script>
<amp-fit-text width="300" height="45" layout="responsive" max-font-size="45">

Instead of the <h1> tag

Expected result


You can get the source code from here:

And get the compiled module from:

Going further

Support for files in rich text

This example assumes that the rich text used for the news is pure valid HTML with no image in it. The filter can be improved to change all the <img> tags to the corresponding AMP tags. The same way for video or other resources

Support for links

The goal of an AMP page is to be cached, meaning that the links within a page are not known until other pages are in cache. Google provides an API to get available links from its cache. You can find more information here:

Further Jahia integration

All the views for the component you want to use in your amp page must be currently created. One of our goal is to provide filters and tools to help content manager build AMP pages from an already stored content and concentrate on their content and let Jahia manage the rendering.