DEV Community

Cover image for Add FULL dev.to posts to your personal site using React.
Iván Roldán Lusich
Iván Roldán Lusich

Posted on

Add FULL dev.to posts to your personal site using React.

I was recently creating my personal website and came to the conclusion that I wanted to add my dev.to posts there too.

After googling a bit I found out this great post by Carl-W, where he demonstrates how to fetch all the post from a single user.

But I wanted to go a bit further and display the full post on my personal website, instead of redirecting everyone to this site.
After checking dev.to public API I found out that you can get the full post by doing a GET request to ('https://dev.to/api/articles/articleId').

The code:

Get post function:

// src/helpers/getPost.ts  


export const getPost = async (articleId) => {
   const URL = 'https://dev.to/api/articles/';

   try{
    const res = await fetch(URL + articleId);
    return await res.json();
   } catch (e){
    console.log('There has been an error fetching the post: ', error);
    /*
     You should handle your errors better than this, but this is just an example and I won't bother. I might do another post on how to handle errors later
    */
   }
} 

Enter fullscreen mode Exit fullscreen mode

Displaying the full post on your site:

Because I don't want to use DangerouslySetInnerHTML because it involves security issues if you don't sanitize the HTML properly and some other stuff, I'll be displaying my posts in markdown, and for that, I'm going to be using react-markdown.

You install it by calling

yarn add react-markdown

or

npm i react-markdown
Enter fullscreen mode Exit fullscreen mode

The use that I'm going to give to this library is very simple, but it's a really powerful tool, and you should check out their full documentation(if you haven't yet. Already linked this above).

I also installed remark-gfm plugin to add a bit more functionalities as indicated here.

Now, to the part that everyone wants to see, the code:

//  /src/component/post.js
import {getPost} from '../helpers/getPost';
import ReactMarkdown from 'react-markdown';
import gfm from "remark-gfm";

//I'm getting the id in another component, but it shouldn't be too //hard, whether you are using CRA or something like nextjs/gatsby.
const Post = ({id}) => {
    const [postInfo, setPostInfo] = useState();

    useEffect(() =>{
      const getAndSetPostInfo = async () => {
          setPostinfo(await getPost(id));
      };

      getAndSetPostInfo();
    },[]);

    if(!postInfo) return null;

    const { title, body, createdAt } = postInfo;

    return {
      <div className={'container'}>
      <div className={'createdAt'}>{createdAt}</div>
      <div className={'title__conainer'}>
        <h1 className={'title'}>{title}</h1>
      </div>
      <div className={'body__container'}>
        <ReactMarkdown className={'markdown__container'} plugins={[gfm]}>
          {body}
        </ReactMarkdown>
      </div>
    </div>
    }    

}


Enter fullscreen mode Exit fullscreen mode

And that's pretty much it! You'll have to add styles to in order to make it look nice, here's the scss code that makes mine look like this:

screenshot from ivanrl.dev showing how markdown was styled in that site.

Relevant scss (The one that styles the markdown):

.markdown__container {
  line-height: 1.6em;
  font-size: 18px;

  h2 {
    font-size: 24px;
    margin-bottom: 35px;
  }

  p {
    width: 100%;
    margin-bottom: 20px;
    img {
      display: block;
      margin: auto;
      width: 100%;

      @include mquery(600) {
        width: 80%;
      }

      @include mquery(800) {
        width: auto;
      }
    }

    a {
      text-decoration: underline;
    }
  }

  pre {
    margin-bottom: 20px;
    width: 100%;
  }

  code {
    background-color: $main-color;
    padding: 5px;
    margin-top: 10px;
    margin-bottom: 10px;
    width: 100%;
    display: block;
    overflow-x: auto;
  }
}
Enter fullscreen mode Exit fullscreen mode

There's one little caveat though, at the moment I haven't yet figured out how to make the # for heading functionality from markdown to work with this component. So I'm currently using ===== and ----- for headings, but that way only allows for h1 and h2 tags. I'll look for a fix and update this post later.

And that is it! I hope someone finds this useful! Thanks for reading!

Top comments (0)