Connecting Medium with Gatsby in less than 5 minutes

Varchasvi Pandey
6 min readOct 13, 2021

--

In this quick story, we will see how we can connect any Medium account with our Gatsby website to fetch Medium stories and creating dynamic story pages on the fly.

Better blogs with Medium and Gatsby

Understanding before coding

Let us first understand what exactly we are going to do. The first question that comes to our mind is whether or not Medium provides us with some API that can aid the integration process. The simple answer to this is “No” and “Yes”. Wait, was that simple? Anyways, Medium does provide us with an RSS feed URL. Here’s what Medium has to say about it. (Open this link in the browser if it’s giving 404 on medium app) Do read it before moving on.
Now that we know what exactly RSS can do, let’s understand how it works.

Let’s first start with the RSS URL provided by Medium. Check out this link and try hitting this URL after replacing “@varchasvipandey” with your Medium username.

https://medium.com/feed/@varchasvipandey

If you can see an XML page document tree like the one shown below, then congratulations, you have successfully fetched your Medium posts. Here’s a party popper for you! 🎉

Medium RSS URL XML Response

Now let’s shift the gear and pick up some speed since we have to integrate this feature in the next four minutes!

How to make it work?

By just looking at the URL response I am sure you must be thinking, how on the earth is this response useful for the integration. Yes, you are right. To integrate this RSS response into our Gatsby site, we need to transform this response into a suitable format. For us, JSON is the best format we can think of. For that, take a look at this API which can convert RSS into JSON.
In the only available field, paste your Medium RSS link and hit the button which says “Convert to JSON”.

rss2json response for Medium RSS URL

Here is another party popper if you got a response that looks similar to the one shown above! 🎉

Now having this knowledge and these tools, let’s move on to the coding part, in the next section.

Integrating Medium with Gatsby

For this section, I am assuming that you already have your Gatsby project all set up with you. Let’s first go through the steps which we’ll be taking in this section-
1. Creating/updating the gatsby-node.js file.
2. Creating/updating the “createPages” function.
3. Logging the data into the console from dynamically generated pages.

To make things simpler to understand and follow, I am considering an empty gatsby-node.js file. Let’s get started!

Creating gatsby-node.js file

At the root of your project create a new file: gatsby-node.js
This file exports all the functions that need to be executed during the build. That is exactly what we want. We want to create static pages during the build pre-populated with our Medium stories.

Creating “createPages” function

This will be an asynchronous function. This function needs to be exported to make it available to Gatsby for execution.

module.exports.createPages = async ({ actions: { createPage } }) => {
/* createPage function is destructured since that is the only action we need for this feature */
};

Let’s now use the Medium RSS URL along with RSS to JSON conversion API. For that let’s first import “fetch” from “node-fetch”.

const fetch = require('node-fetch');

module.exports.createPages = async ({ actions: { createPage } }) => {
const username = 'varchasvipandey';
const mediumRss = `https://medium.com/feed/@${username}`;
const ENDPOINT = `https://api.rss2json.com/v1/api.json?rss_url=${mediumRss}`;

const response = await fetch(ENDPOINT);
const json = await response.json();
};

Now we need to use our “createPage” action. This action will be used twice, once for making a page containing a list of blogs and for creating pages for each available blog. Let’s start with the blog list page.

const fetch = require('node-fetch');

module.exports.createPages = async ({ actions: { createPage } }) => {
const username = 'varchasvipandey';
const mediumRss = `https://medium.com/feed/@${username}`;
const ENDPOINT = `https://api.rss2json.com/v1/api.json?rss_url=${mediumRss}`;

const response = await fetch(ENDPOINT);
const json = await response.json();

// on successful fetch
if (json.status === 'ok') {
// Create page to list blogs
createPage({
path: `/blog`,
component: require.resolve('./src/templates/BlogHome/BlogHome.tsx'),
context: { mediumBlogs: json.items },
});
console.log(`Page created at /blog`);
}
};

What are we doing here?
Here we are calling the “createPage ” action which takes a configuration object. This object contains -
1. path, where the static page needs to be served.
2. component or in this context a template, that will contain the required UI and functions (we will create that in a while).
3. And finally, context, which will be available in our template inside the props with the name “pageContext” like, props.pageContext

Now let’s create pages for each blog.

const fetch = require('node-fetch');

module.exports.createPages = async ({ actions: { createPage } }) => {
const username = 'varchasvipandey';
const mediumRss = `https://medium.com/feed/@${username}`;
const ENDPOINT = `https://api.rss2json.com/v1/api.json?rss_url=${mediumRss}`;

const response = await fetch(ENDPOINT);
const json = await response.json();

// on successful fetch
if (json.status === 'ok') {
// Create page to list blogs
createPage({
path: `/blog`,
component: require.resolve('./src/templates/BlogHome/BlogHome.tsx'),
context: { mediumBlogs: json.items },
});
console.log(`Page created at /blog`);

// Create blog pages for individual posts
json.items.forEach((item) => {
const slug = item.title.toLowerCase().split(' ').join('-');
createPage({
path: `/blog/${slug}`,
component: require.resolve('./src/templates/Blog/Blog.tsx'),
context: { item, url: `https://varchasvipandey.com/blog/${slug}` },
});
console.log('Page created at ' + `/blog/${slug}`);
});
}
};

What are we doing here?
Here we are doing exactly what we did for the blog list page. But, in this case, we are creating multiple pages, hence we need to create a path for each page as well. For that, I have written a simple conversion which is converting the blog title into a lowercase hyphen separated string. Make sure this stays unique, you can do that by giving different titles to your blogs (obviously).

In this case, we are using another template “Blog.tsx” which will contain the blog info in props.pageContext, which will be used to render the blog.

All we have to do now is to check if we are getting the right data in the context or not. Since this is not a blog on UI, I will skip the UI coding part, but if you are interested in the UI as well, feel free to check out my website repository on GitHub. You can also star the repo, I won’t mind at all 😉.

Logging the data into the console from dynamically generated pages

Now, the moment of truth! Let’s create a file “BlogHome.tsx” at the same location as coded above.

import React from 'react';

export interface MediumBlog {
title: string;
pubDate: string;
link: string;
guid: string;
author: string;
thumbnail: string;
description: string;
content: string;
enclosure: object;
categories: string[];
}

interface BlogHomeProps {
pageContext: {
mediumBlogs: MediumBlog[];
};
}

const BlogHome: React.FC<BlogHomeProps> = ({ pageContext: { mediumBlogs } }) => {
console.log(mediumBlogs);
return (
<Layout>{/* UI Here */}</Layout>
);
};

export default BlogHome;

Here’s what we have now. A nice list of blogs fetched straight from Medium!

Blogs list page

Now let’s create “Blog.tsx” at the right location as coded above and log the result for a blog.

import React from 'react';
import { MediumBlog } from '../BlogHome/BlogHome';

interface BlogProps {
pageContext?: {
item: MediumBlog;
url: string;
};
}

const Blog: React.FC<BlogProps> = ({ pageContext }) => {
if (!pageContext) return null;
const { item } = pageContext;
console.log(item);

return (
<Layout>{/* UI Here */}</Layout>
);
};

export default Blog;

Remember the slug? Yes, to check the result visit “/blog/${slug}”. Use any slug to test, for this case we will go with the very first blog on this list.

Blog page with Medium blog data

And there you have it! Your very own static website with integrated Medium stories.

I hope you enjoyed reading this post and found it helpful and informative. If so, do share it with your geeky friends and let them know that they can use Medium as CMS!

Liked what you just read? Read more such blogs
Want to dive deeper into the templates and UI shown above? Check out this repository

I will see you in the next one, until then👋

--

--

Varchasvi Pandey

I draw, build architectures, write code and magically create full stack applications! I sometimes write how I did it and what gotchas I came across!