Showcasing Medium Articles on Your NextJS Website
20 November 2023The Challenge
Sharing your thoughts and projects through blogs can solidify your knowledge and attract an audience. I wanted to feature my articles on my personal website, but I realized the benefit of using well-established platforms like Medium for greater visibility. Yet, I still aimed to display some of these articles on my site so that visitors to my website won’t have to visit a separate link to view some of the articles that I’ve written. Therefore, I sought solutions to:
- Gather essential data (titles, content, images) from my Medium articles automatically.
- Present this data effectively on my website.
The RSS Feed Solution
Medium offers RSS feeds (a web feed format) that allow API calls to fetch the latest articles. To simplify data handling for my NextJS-built website, I used rss2json.com to convert the feed into JSON format.
See the result at minseokim.me/articles.
Fetching Data via API
Here’s a simple function to retrieve Medium posts via an API call:
export const getMediumPosts = async () => {
// API call to convert Medium RSS to JSON
const response = await fetch("https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fmedium.com%2Ffeed%2F%40minseo_kim");
const data = response.json();
return data;
};
This function returns a JSON Object with status indicators, feed data, and an array of Medium articles.
Server-Side Rendering
Using NextJS’s server-side rendering (SSR), I employed getStaticProps() to pre-generate HTML files for production. The code snippet below demonstrates how data retrieval occurs, which are then passed as props to respective components:
export const getStaticProps = async () => {
// Fetching Medium posts
const { status, feed, items } = await getMediumPosts();
// Error handling
if (status === "error") {
return {
props: {
status,
url: "https://medium.com/@minseo_kim",
},
};
}
// Consolidating categories for filtering
const categoriesDict = {};
items?.forEach((item) => {
const categories = item.categories;
// Logic for categories aggregation
});
return {
props: {
status,
feed,
items,
categories: categoriesDict,
},
revalidate: 3600, // Refresh data every hour
};
};
The useEffect() function in React helps filter articles based on selected categories, offering a smoother user experience.
const BlogsPage = (props) => {
const { status, feed, items, categories } = props;
const [filteredArticles, setFilteredArticles] = useState(items);
const router = useRouter();
const searchCategory = router.query.category;
useEffect(() => {
if (searchCategory === undefined || searchCategory === "") return;
const newArticlesArray = items?.filter((item) =>
item.categories.includes(searchCategory)
);
setFilteredArticles(newArticlesArray);
}, [searchCategory]);
return (
<div>
<h1>Latest Articles</h1>
{status === "ok" ? (
<BlogsContainer
posts={filteredArticles}
feed={feed}
categories={categories}
/>
) : (
<p>
Error in retrieving articles, please visit{" "}
<a href="https://medium.com/@minseo_kim">this Medium Feed</a> to check
out more articles!
</p>
)}
</div>
);
};
I will not go into the details of the components, but here’s a snippet of the UI which will display the preview of each Medium article:
Rendering Article Components
To display individual articles, I utilized dynamic routes in NextJS. On top of using getStaticProps, getStaticPaths will make sure that necessary pages pertaining to the articles are pre-generated during build time. The code below shows how it can be implemented:
export const getStaticProps = async (context) => {
// Fetch individual article data
const { params } = context;
const postData = await getSingleMediumPost(params.postId);
return {
props: {
postData,
},
revalidate: 3600,
};
};
export const getStaticPaths = async () => {
// Generating paths for individual articles
const { items } = await getMediumPosts();
const postIds = items.map((item) =>
item.title.toLowerCase().split(" ").join("-")
);
// Logic for generating article paths
return {
paths: postIds.map((postId) => ({ params: { postId: postId } })),
fallback: false,
};
};
Finally, rendering the article content safely involves sanitizing HTML strings using isomorphic-dompurify before using dangerouslySetInnerHTML. As mentioned in the React documentation, dangerouslySetInnerHTML must only be used when the data source is trusted and sanitized.
Conclusion
In conclusion, leveraging Medium’s RSS feed enables seamless integration of Medium articles onto a personal website. I would like to thank Asiful Alam Fahim and his article on integrating Medium articles on his website.
Check out the following links for my personal website and the source code on GitHub respectively. Thanks for reading!
Stackademic
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us on Twitter(X), LinkedIn, and YouTube.
- Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.
Showcasing Medium Articles on Your NextJS Website was originally published in Stackademic on Medium, where people are continuing the conversation by highlighting and responding to this story.