Add blog posts to personal site using DEV.to API, React and React hooks.
Tags: portfolio, api, react, hooks
Published: 2020-04-23 06:17:46

---
cover_image: https://images.unsplash.com/photo-1517336714731-489689fd1ca8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&h=980&w=1920
title: Add blog posts to personal site using DEV.to API, React and React hooks.
published: true
description: In this post I show how you easily can request your blog posts from the DEV.to api and add them to your personal site using React and React hooks. Best headless CMS for your programming portfolio.    
tags: portfolio, API, react, hooks
---

I have recently been thinking of doing more blogging and with that also comes decisions around the technology which I want to power the endeavour. 

## I came up with a few points that was important to me:

* Write posts in markdown.

If I want to move the content, then I don't want to spend time on formatting it.

* One platform to distribute the content.

To extend my reach I want the content to be published at one or more, platforms which has traffic from developers. But, I also want the content available on my personal site. That means I want to publish to a platform that has an open API (bye bye medium)

* As little effort as possible.

I don't want to handle hosting WP, or a full featured headless CMS somewhere. And I want writing the posts in a web interface without thinking about weird quirks. 

## Enter dev.to
- The DEV.to API is open, which means If I post an article here I can get that content into my site without much effort. 
- Posts are written in markdown & handles images for me.
- Already have heavy traffic from other developers.
- It's free. 

## TLDR: The code

After visiting the docs site of dev.to I learned that getting the posts of a certain user was as easy as doing a GET request with a query parameter of the user. 

Below is a curl command:

```
curl --request GET \
  --url 'https://dev.to/api/articles?username=ugglr'

```

If you paste this link into a curl enabled terminal and switch out the username parameter you'll get the posts of that user. 

I have implemented a function that does this in Javascript and using superagent. You could just as easy use Fetch or Axios, I just like superagent. 

### Get Posts Function
```
// function for getting my blog posts from dev.to.
const getPosts = async () => {
  const DEV_TO_URL = "https://dev.to/api/articles"

  try {
    const result = superagent
      .get(DEV_TO_URL)
      .query({ username: "ugglr" })
      .then(res => {
        return res.body
      })
    return result
  } catch (error) {
    console.log("WE HAVE FETCH POST ERROR", error)
  }
}
```

You could store that in a file and export the function to share between components, or just keep it in the same file as the consuming component. 

### Adding the posts to your site

I have just done the most simple version where I link to the post and redirect the user if they want to read more. 

```
################## React Blog Component ###################

const Blog = () => {

  /* initialising the state which will hold the posts information
     and the loading state, so we can have a loading placeholder on
  */ our site.

  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(true)

  /*
     Use effect is the old lifecycle equivalent of ComponentDidMount()
     With the added empty array in the second parameter, this will run
     once when the component mounts. 
  */ 

  useEffect(() => {
    getPosts().then(res => {
      // I like to print so I know where things are happening
      console.log("IN USE-EFFECT", res)
      // Set the state using hooks syntax 
      setPosts(res)

      // Set loading to false
      setLoading(false)
    })
  }, [])

  // Print the data for easy debugging
  console.log("Posts state", posts)

  return (
      <div>
        {/* If we are loading, show loading placeholder */}
        {loading && <h1>loading posts...</h1>}

        {/* If we have loaded the posts display them */}
        {!loading &&
          posts.map(post => {
            return (
              <Card
                imageSrcPath={post.cover_image}
                title={post.title}
                date={post.published_at.slice(0, 10)}
                description={post.description}
                leftButtonText="Read More"
                sourceURL={post.canonical_url}
              />
            )
          })}
      </div>
  )
}

export default Blog
``` 

Here's how it looks on my site.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wkrmanov1imvonb8drak.png)

In my opinion this method is hard to beat for a small personal devloper portfolio page. It's like a headless CMS, it's free, and offers more exposure.


Hope someone will find it useful, thanks for reading!