Was this page helpful?

Building your first app

The demo app maker we're about to build is called Blog Post Metrics. Whether you are a developer in a startup with no code experience or a seasoned professional, this will enhance your app development process and editorial experience when creating a blog post by providing useful metrics such as word count and a reading time indicator. The metrics will be shown in the entry editor in the sidebar for a given blog post entry.


In order to successfully complete this tutorial:

  • You'll need the latest LTS version of Node.js installed on your machine. If you don't have Node.js installed, you can download it here.
  • You should be comfortable using your computer’s command line and text editor.
  • You’ll need to be able to read and write HTML, CSS, and JavaScript (Java and Swift are not supported).
  • You should be familiar with installing software using the Node package manager.
  • You'll need a free Contentful account and Contentful space. You can sign up here.

What to expect

In this tutorial you'll learn:

  • How to create an app.
  • How to configure where your app is shown in the web app.
  • How to install an app into your space.
  • How to choose which content type your app interacts with.

If you prefer to start tinkering directly, you can clone the example code and go from there.

Table of contents


We will use several tools and libraries throughout the tutorial. We choose these software development technologies because we think they provide the best app developer experience possible.


We use React to render our views for the app and handle our logic. React is a JavaScript library for building user interfaces. However, using React is not mandatory to create free apps.


The App SDK provides the methods that are necessary to interact with the Contentful web app. We will only use a subset of the methods, but if you want to know the full scope of what is possible, take a look at our App SDK reference documentation.

Forma 36

We use Forma 36 to achieve the same look and feel of the Contentful web app. Forma 36 is Contentful's design system.


The app is written in TypeScript. However, you do not need any TypeScript knowledge in order to complete this tutorial. Apps can also be written in JavaScript programming lanaguage without losing any of the functionality.

Set up your content model

Create a content type

Before we start, make sure to have a content type set up and an entry we can test the app idea on. If you are coming from a beginner's perspective and not familiar with the concept of content types, you can read more about content types here. If you already know how to create a content type, you can skip this section.

  1. Go to your content model page.
  2. Click on Add content type.
  3. Enter the name of the content type you’re creating (in this case, “Blog post”) and a short description. Then click Create when satisfied.

Create your content type

If you already have a content type called Blog post, rename the content type as you like. However, for the rest of the tutorial, we will assume that the content type is called Blog post.

Set up your fields

The next step is to define what kind of information should be stored for each blog post. This is done by adding fields. For our Blog post content type, we’ll be using two types of fields:

  • Text
  • Long text

To add fields:

  1. Go to your content model
  2. Click the Add field button and select Text. Give the new field the name of Title and click Create.
  3. Click the Add field button and select Text. Give the new field the name of Body. Select Long text, full-text search and click Create.

When finished adding fields, click Save.

Your content type should look like this:

Content type Blog post

Make sure you name your Long text field Body so it has a field ID called body.

Set up your project

As a first step, you need to create a project directory where you can work in. We will use a great app builder tool called create-contentful-app. This tool makes it easy to create apps with React and Forma 36 and offers a modern build setup with no configuration.

npx create-contentful-app my-first-app

After some time our script is ready and initializes our first app. Navigate to the newly created folder and start the app.

cd my-first-app
npm run start

This hosts your application on http://localhost:3000. We'll later connect to this through the Contentful web app

Embed your app in the Contentful web app

In order to you see your app running in the Contentful web app, you need to create an AppDefinition to expose the app to Contentful. An AppDefinition is an entity that represents an app in Contentful and stores general information about it.

Create your AppDefinition

Go the to the management view for your apps. This management view lives under your organization settings since AppDefinitions are bound to your Contentful organization.

If this isn’t your first app, then the Create app button will be in the top-right corner of the Apps page.

Click on Create an app and you will be redirected to a page where you can provide details about your app.

  1. Provide a name for your app. This can be whatever you want, we chose Blog Post Metrics for this tutorial.

  2. Enter an app url. This is the url where our app is running. Since we are running our app locally the url is http://localhost:3000.

  3. Specify the app locations. Since we want to see the metrics for our blog posts in the sidebar of the entry editor, we check the location Entry sidebar. Additionally, we select the location App configuration screen, as we will be using this location at a later stage.

App locations specify where our app can appear in the Contentful web app. For more details, see our app location documentation, which explains the benefits of rendering your app in different locations.

Click on Create app when you are done filling in the details.

Create your AppDefinition

Install your app

After you created your AppDefinition, navigate back to your space. Your app should appear on the app listing page under Apps > Manage Apps.

Go to your app listing page

WIP: Private app marketplace

Click on your app and you will be asked to authorize access for your new app.

Authorize your app

Confirm the dialog and you will be taken to your config screen of your app.

If you see your config screen that means our app was successfully loaded and embedded in the Contentful web app.

Click the Install button to install your app.

Install your app

Congrats, your app is now installed to your current space and environment! 🎉

Configure your app

The config screen is rendered by the ConfigScreen component. Lets fire up our code editor of choice and open our project that was generated by create-contentful-app. You will find the component under src/locations/ConfigScreen.tsx. Any changes you make here will be reflected in the Contentful web app. Let's change our headline from App Config to Blog Post Metrics Config.

Save the file to your desktop and watch the config screen update in real time.


Assign your app to a content type

Now that you have installed our app, you can assign it to your content type Blog post that you created earlier.

  1. Go to your content model page and click on the content type Blog post.
  2. Click on the sidebar tab.
  3. Click the + button on the Blog Post Metrics card and the app will be assigned to the sidebar.

Do not forget to click the Save button in the top right corner to save your configuration. You can even change the order in which the sidebar widgets should appear by dragging the cards up and down.

See your app in action

Go to your content tab and create an entry with the content type Blog post. You should see a sidebar app now in your entry editor.

Sidebar Content Type

Lets open the Sidebar component in our project. All the component does is return a paragraph saying Hello Sidebar Component.


import React from 'react';
import { PlainClientAPI } from 'contentful-management';
import { Paragraph } from '@contentful/forma-36-react-components';
import { SidebarExtensionSDK } from '@contentful/app-sdk';

interface SidebarProps {
  sdk: SidebarExtensionSDK;
  cma: PlainClientAPI;

const Sidebar = (props: SidebarProps) => {
  return <Paragraph>Hello Sidebar Component</Paragraph>;

export default Sidebar;

All the changes you make here to the component will also be reflected directly in the web app.

Calculate the metrics

Let's provide some metrics for the blog post. For calculating the word count and the reading time we will use a library called reading-time. Navigate to your project folder and install the library with:

npm install reading-time

We can use the sdk object, which gets passed into every view, to interact with data in Contentful. The sdk.entry.fields object holds all the fields that are in an entry. We can get an individual field by its fieldId, in this case body as we specified it when creating our content type.

Next we need to store the information about the blog post in state to render the appropriate information. We use the getValue method to retrieve the current value from the field.


import React, { useState } from 'react';
import { PlainClientAPI } from 'contentful-management';
import { Paragraph } from '@contentful/forma-36-react-components';
import { SidebarExtensionSDK } from '@contentful/app-sdk';

interface SidebarProps {
  sdk: SidebarExtensionSDK;
  cma: PlainClientAPI;

// The field ID from our blog post field
const CONTENT_FIELD_ID = 'body';

const Sidebar = (props: SidebarProps) => {
  // The sdk allows us to interact with the Contentful web app
  const { sdk } = props;

  // With the field ID we can reference individual fields from an entry
  const contentField = sdk.entry.fields[CONTENT_FIELD_ID];

  // Get the current value from the blog post field and store it in React state
  const [blogText, setBlogText] = useState(contentField.getValue());

  return <Paragraph>Hello Sidebar Component</Paragraph>;

export default Sidebar;

If we want to calculate our wireframe metrics as soon as somebody starts writing content for a target audience through a blog post, we need to listen to onChange events from the field. The sdk provides a field API which we can leverage to listen for value changes the app needs. We use the method onValueChanged to listen for any content updates on the landing page and call a method readingTime which will take the value and calculate our desired metrics. It will do all the heavy lifting for us and return an object which holds the word count and the time-consuming metrics of reading time.

The last thing we want to do is display the calculated metrics in our sidebar. For this we import a few Forma 36 components. We will use the List, ListItem and Note component to give our app design the look and feel of the Contentful web app. The final code of the app development should look like the following screenshots.


import React, { useState, useEffect } from 'react';
import { PlainClientAPI } from 'contentful-management';
import { List, ListItem, Note } from '@contentful/forma-36-react-components';
import { SidebarExtensionSDK } from '@contentful/app-sdk';
import readingTime from 'reading-time';

interface SidebarProps {
  sdk: SidebarExtensionSDK;
  cma: PlainClientAPI;

const CONTENT_FIELD_ID = 'body';

const Sidebar = (props: SidebarProps) => {
  const { sdk } = props;

  const contentField = sdk.entry.fields[CONTENT_FIELD_ID];

  const [blogText, setBlogText] = useState(contentField.getValue());

  // Listen for onChange events and update the value
  useEffect(() => {
    const detach = contentField.onValueChanged((value) => {
    return () => detach();
  }, [contentField]);

  // Calculate the metrics based on the new value
  const stats = readingTime(blogText || '');

  // Render the metrics with Forma36 components
  return (
      <Note style={{ marginBottom: '12px' }}>
        Metrics for your blog post:
        <List style={{ marginTop: '12px' }}>
          <ListItem>Word count: {stats.words}</ListItem>
          <ListItem>Reading time: {stats.text}</ListItem>

export default Sidebar;

You should see now see your first-time app in your sidebar. Type some content in your field and see how the new feature app updates!

Congrats on building your first successful app !🎉

You can find the full example code app here.


To deploy your app coding skills and make it available through a marketing strategy or social media to everyone in the app market, you need to create a production build of your app. Our CLI tool create-contentful-app provides a build script. To build, run the following command:

npm run build

One of the quickest ways to host your own apps and the optimization of the user experience is Contentful app hosting with little development cost. In the app's root directory, run this command:

npm run upload

The script, by default, will upload your output directory (i.e.: ./build) and will allow everyone in your organization to use the app's cross-platform functionality.

Similar to creating an app definition with our CLI tooling, you will need to log in, select an organization and app definition. Alternatively, you can provide this information through environment variables (CONTENTFUL_ACCESS_TOKEN, CONTENTFUL_ORG_ID, CONTENTFUL_APP_DEF_ID). You can read more about it here.

Additional Resources