Next.js + serverless personal webpage in a couple of hours — Pull Medium posts with Serverless Function (Part 6)

Jeremy Chan
Level Up Coding
Published in
5 min readFeb 22, 2021

--

What I want to achieve is to provide a more seamless experience when users click on the “Blog” button on my webpage. I want to display in my webpage a list of recent posts that I have published on Medium and keep them up to date automatically.

This is part 6 of a series of posts I made for documenting my journey of setting up my personal webpage in an evening:

Part 1: Development Environment Setup
Part 2: Purchasing your own domain name and set up email forwarding
Part 3: Bootstrapping the app with Next.js
Part 4: Deploying to Production with Vercel
Part 5: Integrate your contact form with Formspree
Part 6: Pulling blog posts from Medium with a serverless function(📍 You are here)

Pulling data from Medium’s RSS feed (120 mins)

A natural approach is to pull data from Medium is to use their REST API. After some research, I concluded that Medium’s API only provide interfaces for creating publications and not fetching publications. You may ask why, but I guess one obvious answer is that they want to readers to read from their platform instead of consuming content from third-party services.

However, Medium does provide an RSS feed that contains excerpts for an author’s publications at https://medium.com/feed/@author-handle. This will work - we just need to parse the RSS feed (which is in XML)and format the data in JavaScript right?.

CORS problem

You may be tempted to fire an XHR request using JavaScript from the client-side to retrieve data from Medium’s RSS endpoint. This unfortunately will fail as the response from the Medium RSS endpoint does not include the Access-Control-Allow-Origin header. All modern broswers respect the CORS policy and will refuse to let JavaScript code access those responses.

Any workarounds?

One option is to use a free/public CORS proxy which acts as a middleman and adds the Access-Control-Allow-Origin to the response. This approach puts a lot of trust into the proxy provider and your webpage is now also dependent on its availability. cors-anywhere used to be an open proxy on Heroku. This is no longer the case as of Jan 2021.

This brings us to two options:

  1. Run our own CORS proxy
  2. Setup an API Gateway using a serverless function

Running our own CORS proxy is more involved in terms of the infrastructure and cost. I’m going with Option #2. There are a few options when it gets to serverless functions, AWS lambda being the most popular. Yet, since our deployment already lives in the Vercel ecosystem, it makes sense to use serverless functions provided by Vercel as well.

Let’s start with the hello world function

When you created your app with create-next-app , it already gives you an example hello world function in the /api folder of the project root. By default, any functions under /apiare automatically hosted and exposed by Vercel with a HTTP endpoint.

Navigate to https://yourdomain.com/api/hello, you should see the JSON response.

On Vercel, navigate to your deployment and go to Functions. It shows realtime logs for your serverless functions.

Testing your function locally

While it’s quick to deploy and test on Vercel. It’s still quicker if we are able to test the serverless functions locally when we are doing development. The Vercel CLI provides this functionality by replicating the production environment on Vercel. Install the CLI by running:

npm i vercel

Then instead of npm run dev, start the local dev server by:

npx vercel dev

Under the hood it also use next dev to watch for changes in your project directory, but you can now also invoke your functions by going to http://localhost:3000/api/hello

Dumping the Medium RSS feed in our function

Let’s do a proof of concept by creating a function to dump the entire RSS feed for my account https://medium.com/feed/@jeremy-chan

First we need some http client to fire the request from the serverless function. We are going to use axios:

npm i --save axios

Vercel will automatically install dependencies in package.json for your serverless function.

Now let’s write some code to dump data from the RSS feed:

Navigate to http://localhost:3000/api/medium and you should see the content of the XML dumped into the text field of the JSON response.

Try deploying it on Vercel and see it live.

Converting XML to JSON

We can convert the XML response to JSON using the xml2js package.

npm i --save xml2js

Modify the code above to convert the XML to JSON and return in the response. We also selectively extracted only the information we need from the converted JSON to keep our response nice and clean.

Hit your API again and you should see the RSS feeds converted to JSON format like below:

Displaying the content in your webpage

With an API under the same domain name that proxies the Medium RSS XML and returns a nice JSON, we just need to glue the pieces together and render the “Blog” component in our UI using the API response.

Here we hit our API in the useEffect function of the component. We pass an empty array [] as dependency for the function so useEffectonly runs once when the component is rendered. We save the posts fetched from the API into a local state and render it into a list of <div>.

The end result looks like this. With serverless function the webpage is kept in sync whenever a new post is published.

Conclusion

This concludes the series. I’m happy with how much I’ve learned and achieved in an evening. I’m also impressed with the pleasant developer experience that Next.js and Vercel provide for deploying static webpages.

Total time spent: ~4 hours
Total expense: £10
Number of times getting stuck: 0

Part 1: Development Environment Setup
Part 2: Purchasing your own domain name and set up email forwarding
Part 3: Bootstrapping the app with Next.js
Part 4: Deploying to Production with Vercel
Part 5: Integrate your contact form with Formspree
Part 6: Pulling blog posts from Medium with a serverless function

--

--

I’m a Software Engineer and a technolgoy enthusiast based in London. Also an aspiring conference speaker.