Blog feature on a React app using Dev.to as a Headless CMS
Tags: react, headlesscms, blog, productivity
Published: 2023-03-28 20:55:13


To fully understand this post, I am assuming you are aware of the Headless CMS architecture, an approach to decouple where content is stored from where it is presented.

[Read more about Headless CMS architecture ](url)

Some time ago, I decided to build a portfolio application to show some of my previous work and skills. Thinking about the features present on this portfolio and, knowing that the software development career is an endless road learning journey, why not register things I was learning? Why not share this?

I should write a blog and couple it with this portfolio, I thought...

But what was the cheaper and best approach for this endeavor? 
I had some decisions around the technology to take.

Some points that were important to me, like:

- As little effort as possible: Didn't want to handle hosting or a full-featured headless CMS somewhere like a whole WordPress.org. I have plenty of work to do, don't need to overenginnering this project;
- Write posts in markdown: in case I decided to move content in the future, don't want to have to format everything again;
- Distribute the content: Traffic is important, I want the content to be published on one platform that has traffic from developers;
- Want the content available on my personal portfolio. 

After considering the best and cheaper options available, I found DEV.to and decided to use it to store my articles.

The DEV.to API is open, which means I can easily use it and get that content into my portfolio without much effort. Posts are written in markdown and already have heavy traffic from other developers.

**Decision made, time to get to work!**

## Dev.to as Headless CMS

In this feature for my portfolio, my dev account performs the role of CMS, and the content is presented in a React App. In other words, the backend is powered by Dev.To , the frontend is made using ReactJs and is hosted on Vercel.

As I already had [a portfolio made using React](https://sarahjobs.com/), I had to create new components and routes to implement this blog feature.

The first step was to create the component PostsLists.js.  On this component, we will use the famous React hooks useEffect and useState, so we need to import them:

`import React, { useEffect, useState } from 'react';`

In the Posts.js component, we will get the data from Dev. I could use two different methods of making network requests: either Fetch or Axios. 

**I decided to use Fetch**, as you can see below:

```
export default function Posts () {
  
/* initializing the state which will hold the articles information
and the loading state  */

  const [articles, setArticles] = useState ([]);

/* fetch the articles, change your username to retrieve 
your own articles */

  useEffect( () => {
    fetch('https://dev.to/api/articles?username=sarahcssiqueira')
    .then( (res) => res.json())
    .then((res) =>  {
      setArticles(res);
    });
  }, []);

```

Then, I like to console log to see if everything worked and the array returned:

`console.log(articles); `

As everything is working as expected: 

```
  return (
  <section> 
      {articles.map((article) => {
        return (
          <article key={article.id}>
              <img src={article.social_image} 
                   alt={article.title}>
              </img>

              <Link to={article.url}>
                {article.title}
              </Link>
              <p>
                {article.description} 
                <Link to={article.url}> 
                   <BsBoxArrowUpRight/>
                </Link>
              </p>
              <ul>
                  <li>
                      <BsCalendarDate/> 
                      {article.readable_publish_date}
                  </li>             
              </ul>
              <ul>
                  <li>
                      <AiFillTag/>
                      {article.tags}{" "}
                  </li>             
              </ul>

              <p>
                 <BsChatHeartFill/>
                 {article.public_reactions_count} 
             </p>
          </article> 
          )
    })}      
  </section>
)};
```

The result can be seen at my portfolio on [blog page.](https://sarahjobs.com/blog)