How I built my First Server-Rendered React/GraphQL app and deployed it on Heroku

Dane David
Chingu
Published in
4 min readMar 7, 2019
Pic Courtesy: Unsplash

Note: This is just my experience of issues faced during the process, and the approaches I took to solve them. This is NOT a tutorial or guide.

So I joined Chingu Voyage yet again, with dreams of collaborating with other devs and building side projects. This time around, Chingu had introduced a new selection process, according to which you have to complete a side project ( and a pair programming session ) to get selected into the voyage. The project to be made was a Book Finder application. Learning GraphQL and trying Server-Side Rendering (SSR) has been on my to-do queue for long, so I decided to give them a try.

The GraphQL Part

I had only done one project using GraphQL when I began with this. Here, I tried a new approach: layering GraphQL over an existing REST API. This article helped me greatly to that end. I used apollo-server and apollo-data-source to layer GraphQL resolvers over the Google Books API to server it using GraphQL server. The following code does this:

Doing the rest was relatively simple. If you’re familiar with GraphQL, you know about schemas and resolvers. You have to define any valid types inside schema and resolvers also.

Server-Side Rendering

This was the trickiest part. I had challenged myself from the beginning not to use any out-of-the-box solutions like Next.js, so that I can learn the basics of SSR in React. Using React ( and JSX ) on the server side meant we needed Babel. So I decided to use Webpack to bundle server code. There were many tutorials to that end, but none of them worked completely out of the box. But documentation of Webpack, Express and React helped me well. In the end, I ended up using Webpack to emit 2 separate bundles for server and client, and used the Express router to server the client bundle at / and the Apollo GraphQL server at /api.

Next, I faced problems setting up dev ( local ) environment. I could use nodemon to restart the server, but I couldn’t set up hot reloading on the client. So, I ended up running client on webpack-dev-server on a different port and API server at another, for the dev environment. Separating out the environments solved most of my problems, but now I had to do some checks inside application code as well, like using ReactDOM.render in dev & ReactDOM.hydrate in production, making API requests to different port in dev while same port in production, etc. I’m not sure if there is a better way, but my method seamed to work well as I now had separated config files and scripts for local & production environments.

Wiring up & Deployment

All that was left was developing the React UI components and fetching data from the server to display appropriate components. I thought Apollo Client was too much for my requirements, so I used Prisma’s graphql-request instead. I believe Apollo client uses a more declarative form of fetching and storing data from GraphQL APIs, with support for caching and other stuff. graphql-request on the other hand, provides a simple fetch-like imperative Promise-based function that can be used to query GraphQL end-points. I thought this was simple for my current use case, and ended up using this. The code is pretty straight-forward:

Also, I used Evergreen UI Components as my component library.

Another thing I could achieve was, even though a small number, I wrote all my React components as functional components. I leveraged the React Hooks API for the same. I used Context API for passing the GraphQL client down to all components.

Deploying to Heroku simply required a few simple steps. Installing heroku-cli, then adding Heroku server as a remote for your repo, and then adding a Procfile telling Heroku which npm script to run on deployment. After all set up is done, git push heroku master and the deployment is done!

You can view the deployed app at https://chingu-bookfinder-dane.herokuapp.com/ and the entire application code at https://github.com/danedavid/chingu-2019-prework.

I hope I covered most aspects of my development process. I also wanted to make this article short and concise. You can read the code and feel free to reach out to me in case of any doubt. Also leave a comment in case of any suggestion or mistake in the article. Always remember; you can follow a specific tutorial or guide, but the official documentation of whichever library you are using will always be your best friend. And Stack Overflow ;)

--

--

Dane David
Chingu
Writer for

Full Stack Web Developer. Open Source Enthusiast. Avid Traveller. Coding awesome stuff @ SurveySparrow.