Build a Simple Blog with Contentful and React
Tags: typescript, react, contentful
Published: 2020-10-15 03:28:07

## Overview
In this post, I will introduce a way to build a simple web application that is a simple blog with a famous headless CMS, contentful.

## Sample
Here is my code for this post.
repo https://github.com/koji/typescript/tree/master/simple_blog_with_contentful
​
## What is Headless CMS?
Let me tell you what a headless CMS briefly.
Roughly speaking, a headless CMS is a CMS without the functionality of displaying content.
Let's say it is like WordPress that has only a `dashboard`.
Probably, some of you think why we need to use headless CMS instead of other CMSes.
- merits
  -  Can focus on frontend and there is no limitation by a CMS(You can use anything you want to use and the development process is the same as normal frontend development)
  -  In terms of Contentful, it offers the npm package for fetching data

- demerits
  - It would be hard to change looks for non-tech people
  - If a headless CMS gets issues, we need to wait until they will be fixed by a service provider
​
About Contentful
https://www.contentful.com/developers/
Contentful is great since it has good documentation, Slack group, and forum.
​
## Step 1 Define Contentful models
Loggin Contentful and define models to display data on react application.
In this post, I just created 3 items, title, eye-catch image, and body.
​
![](https://storage.googleapis.com/zenn-user-upload/31dk6whf0rtz2s0sspgb324j1tb8)
​
`Data structure`
```js
{
  "name": "easysite", <-- コンテンツモデル名
  "description": "simple website like a blog",
  "displayField": "title",
  "fields": [
    {
      "id": "title",
      "name": "title",
      "type": "Symbol",
      "localized": false,
      "required": false,
      "validations": [],
      "disabled": false,
      "omitted": false
    },
    {
      "id": "image",
      "name": "image",
      "type": "Link",
      "localized": false,
      "required": false,
      "validations": [],
      "disabled": false,
      "omitted": false,
      "linkType": "Asset"
    },
    {
      "id": "description",
      "name": "Description",
      "type": "Text",
      "localized": false,
      "required": false,
      "validations": [],
      "disabled": false,
      "omitted": false
    }
  ],
  "sys": {
    "space": {
      "sys": {
        "type": "Link",
        "linkType": "Space",
        "id": "if4se75018sp"
      }
    },
    "id": "easysite",
    "type": "ContentType",
    "createdAt": "2020-10-01T15:28:51.896Z",
    "updatedAt": "2020-10-01T15:28:52.158Z",
    "environment": {
      "sys": {
        "id": "master",
        "type": "Link",
        "linkType": "Environment"
      }
    },
    "publishedVersion": 1,
    "publishedAt": "2020-10-01T15:28:52.158Z",
    "firstPublishedAt": "2020-10-01T15:28:52.158Z",
    "createdBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "0EGNAqGfBgN849uaItzT7r"
      }
    },
    "updatedBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "0EGNAqGfBgN849uaItzT7r"
      }
    },
    "publishedCounter": 1,
    "version": 2,
    "publishedBy": {
      "sys": {
        "type": "Link",
        "linkType": "User",
        "id": "0EGNAqGfBgN849uaItzT7r"
      }
    }
  }
}
```
​
​
## Step 2　Create content
This step only needs to create an entry that is almost the same as writing a post on `dev.to`. You can use Markdown.

Content --> Add Entry --> easysite(In this case, I named entry model `easysite`)

​
![](https://storage.googleapis.com/zenn-user-upload/epdrlxigvy5okcqot4r9f0cpv6p1)

From the top, title, eye-catch image, and body.​

One thing you should know is that if you publish the body, that doesn't mean you publish the eye-catch image.
You will need to publish them separately.
​
## Step 3 Get the API-Key
You will need to generate API Key from Settings. Then get `SpaceID` and `Access Token`


​
## Step 4 Create React app
Operations on Contentful is over, from this step you just need to develop a react application.

1. Create an app with `create-react-app`
2. Add a component for API-key. In this case, I hardcoded SpaceID and Access Token on the local environment, but if you want to publish this app, you should use environment variables on hosting services such as netlify.
3. Install contentful by yarn/npm
   https://www.npmjs.com/package/contentful  
4. Use contentful to fetch data
5. Parse data and display it
​
This sample uses `useEffect` to get data from Contentful and use `content_type` to specify the target on Contentful (easysite).

* As you know, we should avoid using `any`  lol
​
```ts
useEffect(() => {
    fetchData();
    // console.log(articles);
  }, [articles]);
​
  const fetchData = async() => {
    try {
      const resp = await client.getEntries ({content_type: 'easysite'});
      setArticles(resp.items as any);
    } catch (error) {
      console.log(error);
    }
  }
```
​
`Entry part`
```ts
export const Post = ({ article }: IArticle) => {
    // console.log(article);
    const { title, image, description} =article.fields;
    const postDescription = marked(description);
    return (
        <div className="post">
            <h2 className="title">{title}</h2>
            {image && <img className="featuredImage" src={image.fields.file.url} alt={title} title={title} /> }
            <section dangerouslySetInnerHTML={{ __html: postDescription}} />
        </div>
    )
}
```