Featuring Medium Articles in React Application

Hui Shun Chua
2 min readSep 24, 2020

--

While building my portfolio site, I thought it would be good to feature my Medium articles on it. I envisioned the article links to appear as snippets that look like actual Medium article links. I also wanted the component to auto-update so I don’t have to manually edit the site every time I publish a new article.

Medium articles component

How it works

Step 1: Retrieving article data

The Medium API is not intended for post retrieval, so I had to retrieve the RSS feed via a GET request to https://medium.com/feed/@your_profile and then convert it to JSON format using existing JavaScript libraries. I tried a few libraries, and the one that worked for me was the rss-parser library.

In the process, I encountered the cors policy no ‘access-control-allow-origin’ error, and had to add https://api.allorigins.win/raw?url= in front of the GET url to bypass it.

I also used the useEffect Hook to fetch data every time the component mounts. This ensures that the component data stays up to date.

Step 2: Styling the snippet

The CSS code (for styling) is as follows:

.long-card {
width: 100%;
min-height: 100px;
border: 0.1px solid #343a40;
text-align: left;
color: #afafaf;
display: flex;
margin-bottom: 10px;
}
.long-card:hover {
text-decoration: none;
color: #afafaf;
}
.long-card:hover .title {
color: #AACCFF;
text-decoration: underline
}
.long-card .title {
font-size: 1rem;
font-weight: 600;
color: white;
transition: color 0.2s;
}
.long-card-body {
padding: 40px 30px;
}
.remarks {
font-size: 0.9rem;
}

Putting it all together, in the component’s JavaScript file,

import React, { useState, useEffect } from ‘react’;
import * as Parser from ‘rss-parser’;
export default function Articles() {
const [articles, setArticles] = useState([])
useEffect(() => {
async function getFeed() {
let parser = new Parser();
const rss = await parser.parseURL(‘https://api.allorigins.win/raw?url=https://medium.com/feed/@huishun');
setArticles(rss.items)
}
getFeed()
}, []);
return (
<div className=”articles container-fluid section”>
<h2 className=”section-header”>WRITINGS</h2>
<div className=”section-body section-width”>

{articles.map((article, index) => (
<a href={article.guid} target=”_blank” rel=”noopener noreferrer” className=”long-card” key={index}>
<div className=”long-card-body”>
<h5 className=”title”>{article.title}</h5>
<p className="remarks">{article['content:encodedSnippet'].substring(0, 197)}...</p>
<div className=”remarks”>medium.com</div>
</div>
</a>
))}

</div>
</div>
)
}

Conclusion

The live version can be found in my portfolio site here, and the full code including other parts of the portfolio site is hosted here.

--

--

No responses yet