Building a microsite publishing service with Contentful and AMP

Microsite blog header
November 22, 2019


Let’s dive in

We’ll build a microsite service with AMP and Contentful. This setup could be part of a larger installment but to simplify things, we just think about a smaller part of the whole IT landscape.

Building a content model

First thing we need to do is come up with a proper content model for our microsites. Let’s say we want to build a simple page containing a headline, a copy text and an image to go with it. A call to action might come in handy.

After registering a plan with Contentful, we login and add a content model. For the sake of simplicity, we title it Microsite and hit create. In production, you may want to think a bit longer about choosing this name. A more generic approach for describing this collection of fields might be suitable.

After creating the model, we need to add all the fields we planned earlier. We only use the basic types for our project, but there are a lot of specialized types we could use for a more sophisticated editing experience. However, we use Short text and Media for this example.

Having everything set up, we’re ready to add some content for our microsite. Let’s promote AMP here.

Don’t forget to publish the content. We’ll need to have it available for rendering. If you would like to learn more about Contentful, head over to the documentation page.

Setting up the AMP page template

We will need an AMP template to render our content. AMP is a collection of web components that we could use to build a page, many of which have advanced functionalities. But we’ll continue to keep things simple here.

We’re starting off with some AMP code:

<!doctype html>
<html ⚡>
<meta charset=”utf-8">
<script async src=”"></script>
<link rel=”canonical” href=<%= microsite.url %>”>
<meta name=”viewport” content=”width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>body{ margin: 0; padding: 0; font-family: sans-serif; font-size: 16px; color: #fff; background: #000; overflow-x: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } section{ margin:30px } h1{ font-size: 31px; display: block; color: #45dca5; } a{ margin-top: 30px; font-family: sans-serif; font-size: .9375em; cursor: pointer; background-color: transparent; border: 2px solid #45dca5; display: inline-block; color: #45dca5; padding: 10px 0 7px; box-sizing: border-box; text-transform: uppercase; text-align: center; width: 100%; transition: background-color 0.2s, color 0.2s, font-weight 0.2s; text-decoration: none; transition: background-color 0.2s, color 0.2s, font-weight 0.2s; }a:hover{ font-weight: bold; background-color: #45dca5; color: #000; }</style>
<title><%= microsite.title %></title>
<! — microsite content →
<h1><%= microsite.headline %></h1>
<amp-img src=<%= microsite.image.fields.file.url %>width=”1080"
<%= microsite.copy %>
<a href=<%= microsite.linkUrl %>”><%= microsite.linkText %></a>
<! — /microsite content →

Several noteworthy things happen in this code. Let’s go through it bit by bit. The doctype definition, as well as the html attribute (html amp works also), is required. Next the runtime needs to be loaded, which is done via the script tag in the header. All styles need to be inlined for performance reasons. The canonical tag should point to the original HTML site. In our case there is none, so the URL points to itself.

If you want to learn more about AMP, go and check out the project’s comprehensive website.

We’re going to use ejs as a template engine. To access objects we use the following notation.

<%= object.attribute %>

We’ll take a look into populating the values with a node.js express app in the next section.

Gluing it all together

We’ll set up a simple express app that will fetch and render the content. In a real-life-scenario, this could be extended with caching and scaled horizontally, or be set up to run as a serverless function.

To access our microsite, we’ll use the ID of the entry. After retrieving the key and the space ID from contentful (Settings -> API Keys) we need to setup our express app.

First, we need to install express-generator to scaffold a simple express app with ejs support:

npm install -g express-generator
npx express-generator — view=ejs
npm installsave contentful
npm start

With the basic app scaffolded we can open routes/index,js and edit the file.

const contentful = require(‘contentful’)
const express = require(‘express’);
const router = express.Router();
const SPACE_ID = ‘the space ID goes here’
const ACCESS_TOKEN = ‘your access token goes here’
/* GET home page. */
router.get(‘/:microsite’, function(req, res, next) {
const client = contentful.createClient({
// This is the space ID. A space is like a project folder in Contentful terms
space: SPACE_ID,
// This is the access token for this space. Normally you get both ID and the token in the Contentful web app
accessToken: ACCESS_TOKEN
res.render(‘index’, {microsite: entry.fields});
.catch(err => console.log(err));
module.exports = router;

After restarting the app we can access the microsite via http://localhost:3000/Entry-ID. The Entry ID can be retrieved by clicking the info button on the record in Contentful.


It’s super easy to retrieve content and push it to different touchpoints. The same content could be used on the web to populate a teaser, to fuel an ad or could be integrated in a newsletter. AMP helps to build frontends quickly and make them easily deployable. Contentful can be used to manage all that content in a single place and expose it via a unified API.

There is no need to anticipate future requirements as new touchpoints can be added without new integration efforts.

Overall, a quick time to market to connect a new touchpoint can be achieved with a modest effort.


Jung von Matt/TECH is a data-driven and technology focused boutique within the Jung von Matt group. Jung von Matt is — in terms of awards for both creativity and efficiency — the most successful advertising agency group in German-speaking countries. The agency helps their clients and partners to be digital pioneers by using technology plus data to develop digital platforms, products and services that create momentum. Jung von Matt was founded in Hamburg in 1991 and today, 27 years later, acts as a non-listed corporation with agencies in Germany, Austria, Switzerland, Sweden, Poland, the Czech Republic and China. There are many big names amongst their list of customers such as adidas, BMW, Deutsche Post, DFB, Edeka, Faz, and innogy.

About the author

Don't miss the latest

Get updates in your inbox
Discover how to build better digital experiences with Contentful.
add-circle arrow-right remove style-two-pin-marker subtract-circle