👨🏻‍🔬 What are headless CMS and Contentful?

Contentful is a powerful, highly extensible headless Content Management Software (CMS). It is distributed as a cloud based solution under proprietary license. Pricing are subscription based but you have a fairly reasonable free-tier.

It allows you to manage and organize any types of contents such as your page layout, your articles in a smart and extensible back-office.

🧟‍♂️ What is an headless CMS and how it differs from classical CMS?

An headless CMS is a CMS that is only delivering data as a JSON (or any other kind of data) payload. It doesn’t serve any kind of frontend code such as HTML page nor CSS. It only delivers small chunks of data that are used to build the view later, that’s the principe of separation of concern over the network.

This UI implementation is delegated to the developer that can use whatever he wants to render the content.

A backend framework like Laravel , Spring or Symfony …

, or … …or a frontend framework such as ReactJS, VueJS, Angular or any similar framework.

Those frontend framework are very popular in the famous JAMSTACK architecture which stands for Javascript, API and Markup.

Headless CMS are data and contents centrics and they excel at this.

Now that we know the backend tool we will use, let’s take a look at what will be used to display our data.

🦸🏻‍♂️ What is NextJS and how is it compared to React?

If you read this article you probably already knows ReactJS. And for the sake of the demonstration, we will use one tool based on it, a framework named NextJS.

Developed and supported by a great company, which provide cloud based services (zeit.co), NextJS is a Server Side Rendering framework (SSR) made with ReactJS which allows build performant web applications, either using SSR or static rendering.

💡If you want to learn more about SSR, JAMstack and related things, I’ll drop some links at the end of this article.

⚡️NextJS as a tool to simplify our application development

NextJS is using by default a directory based navigation. Briefly depending on the file we have in the pages folder, the framework will auto-generate the application router.

Having pages/index.js will make the app responds on / endpoint.

will make the app responds on endpoint. Having pages/blog.js will make the app responds on /blog endpoint.

will make the app responds on endpoint. Having pages/tag/react.js will make the app responds on /tag/react endpoint and so on.

will make the app responds on endpoint and so on. Any other URL will be redirected to the default 404 page, which you can of course override.

Using that pattern we can make a very simple app, very quickly and that’s exactly what this article is about: Quick and easy.

Enough talk. Demo time!

🚀 Demo time: A small articles with authors listing using Contentful and React

The following screenshot is a capture of the final page we are going to build. This is a simple two cards page with data that are fetched from a remote Contentful database.

We all know that Batman is the best.

Let’s start by cloning the following repository using this command: git clone https://github.com/ScreamZ/react-contentful-nextjs-tutorial.git .

💡For simplicity purpose, everything has been automated for you using the export tool of Contentful and what is following is just the explanation of what have been done. Feel free to reproduce on your own if you like so.

❶ Configuring Contentful for frontend integration using the JS SDK

➡️ Create an account and a new empty space

For this demo we will need a empty Contenful space, start by creating a Contentful account if you don’t already have one here https://www.contentful.com/sign-up/.

Once this has been done, just keep going and create a new space by choosing free space and Create an empty space as described below:

Wonderful! Your space is now created. We will now need some access keys in order to talk to Contentful API.

➡️ Create Contentful Content delivery and Management keys

We will need two type of keys for that demonstration:

A Management API key , which will be used to import the test content I created into your contentful space.

, which will be used to import the test content I created into your contentful space. And a Content delivery key, that will be used to access content from the SDK in the frontend code.

First start with the content delivery key: to get that one: go to your space click️ Settings, then API Keys and click Add API key to create a new key which point to the master environment. Name it as you which but take note of the Space ID and the Content Delivery API — Access token we will need those later.

Here is my Example Key 1

You can now create a Content Management Key that will be used for the data import. Click Content management tokens tab and click Generate personal token . Just like the others, keep this token we’ll need it soon.

➡️ Importing content and assets into Contentful using the CLI

The Contentful CLI has already been added to devDependencies in your package.json so what you’ll need now is to fill the import.json file at the root of the workspace using the value of the space id and the management key we took above, the names speak for themselves. Do not change the content-file key, it’s a path to the dump folder we will use.

{

"spaceId": "your_space_id",

"managementToken": "your_management_api_token",

"content-file": "dump/export.json"

}

The space ID is used to identify your space within your organization and the management key is used to manage content creation in your Contentful space using the API.

Once done, save and run the following command:

npm install

npx contentful space import --config import.json to start importing the content of the dump folder into your Contentful space.

Your app is almost ready, now I will detail what have been done to get this dataset on the back-office side.

➡️ Explanation of what have been done to generate this content dump

First I created two content models, which are kind of “classes” of content with some fields. This is used to store data by semantic categories.

I have one article and one author content model with respectively 5 and 2 fields.

The article model has a 1–1 author relation, it contains a date, a title, an image which is also a 1–1 asset relation and a rich content field named body.

Also take note that the content type ID on the bottom right corner is article .

Article entity

The author model is a dumb 2 texts fields with firstname and lastname of the author.

Author entity

Then I created 5 contents:

One author, which is me.

Two articles, one with 🦇Batman and one with️ ⚡️Flash .

and one with️ . And I created two assets entity, which are the photo for our both protagonists.

In fact it’s pretty straightforward… If you want to create more, just go ahead to the content menu in the top navbar and do it. (Don’t forget to publish, status is displayed on right top corner).

That guy is badass… isn’t ?

We are done for the backend and the data, let’s see how we can query for all those data now.

❷ Understand Frontend code built using NextJS and react

The frontend is built using React functions for components instead of classes. This way later, you could leverage the React’s hooks usage.

The UI is powered by 👻 Spectre a tiny frontend framework, with simple layout.

As we there is only one page for listing article, we will create an unique pages/index.js file, that will resolve as we seen above to the http://localhost:3000/ URL.

➡️ Fill the config and run the application

Start by filling the config.json file at the workspace root folder, with the keys we generated above. This will be used by the SDK to query contents in your Contentful space.

{

"space": "",

"accessToken": ""

}

Then run npm run dev in your console. This will get the dependencies from npm and boostrap the application.

Now, open http://localhost:3000 in your browser, you should get the app working with the two articles.

Great, let’s see in details how that happened.

The main page

That the main page component, you can find it in pages/index.js , I added some comments to explain what is going on.

Briefly, each time you visit the / URL in the browser, the getInitialProps function is called, it will fetch data from the Contentful database thanks to the specified space ID and content delivery key by using the Javascript SDK.

Then an array of those articles is injected in the props of the page component, and a loop iterate through it to display Post components.

The Post component

It’s also pretty simple, I just parse the values from the Contentful article in order to display it on the UI.

One small note: we are using a Rich Content field type in the article model. In order to do that we need something that convert AST code into HTML, Contentful already provide this using a small library: @contentful/rich-text-html-renderer .

And there we are! Feel free to add more articles and see that the content is changing on each page call!

❸ Build and run production server or use static rendering

From now we were using next in development mode, you can now compile the production server using npm run build , this will optimize the JS bundle for production. Once this as been done, you can whether run npm start to get a SSR ready server that will run getInitialProps to fetch latests contents on each requests or npm run export that will query it one time and generate a static version of the page in the out folder, that can be hosted on a CDN such as Netlify, Now, Firebase Hosting or your own server like NginX.

If you’re interest on that, just leave a comment and I can update the article to show an example.

🙏🏻 Thanks you for reading, hope this helped.

💁🏻‍♂️ You might also be interest in…

➡️ What is Server Side Rendering with JS apps ?

https://ssr.vuejs.org/ is a nice guide to understand SSR even if it’s VueJS based.

https://nextjs.org/features/server-side-rendering

➡️ JAM Stack

This awesome guide https://jamstack.org/ about JAM Stack architecture.

https://jamstack.wtf/

https://www.gatsbyjs.org/

🚛 Wrapping up / TLDR; 📦

All the article code stands in the following repository: https://github.com/ScreamZ/react-contentful-nextjs-tutorial.