Building JAMStack powered react-static sites using GraphQL on Postgres
TL;DR: Source data from your existing postgres database for your react-static site. Instant setup. Tutorial/boilerplate 👉 react-static-graphql
react-static is a progressive static site generator for React. It is designed to be highly performant and supports custom query layers like GraphQL. It is a popular JAMStack framework.
In this post, we are going to focus on the API part of JAMStack which allows us to build powerful static sites. All database actions are abstracted into GraphQL APIs (Hasura in this case) and accessed over HTTPS with JavaScript. Hasura provides GraphQL APIs on top of Postgres. So it can be leveraged effectively to build a site with react-static, which will be the Markup part of JAMStack.
Deploy Hasura
Follow the instructions in the readme to deploy Hasura and create the tables author and article required for the app. Note the Heroku URL for GraphQL Endpoint. You will be configuring this in the app.
Clone and Run app
The demo app walks you through to build a simple blog app, listing all authors and articles written by each author. You can clone and run the app for the demo.
$ git clone git@github.com:hasura/graphql-engine.git
$ cd graphql-engine/community/sample-apps/react-static-graphql
$ yarn install
After installation, you will have to configure the GraphQL endpoint that you got above. Open src/apollo.js and configure the endpoint
Now run the app:
$ yarn start
You should be seeing the react-static homepage looking like:
If you had added sample data to authors and articles as mentioned in the readme, you can navigate to /blog and see the data templated on the UI.
Implementation Details
Now that you have looked at the demo app, let's look at what is happening behind the scenes. For this app, we need to fetch data from Postgres and template it on a react component. The data to be fetched is simple; article and author. The GraphQL query in Hasura for fetching all authors would look something like
query {
author {
id
name
}
}
and the query for fetching all articles written by an author would look something like this
query($author: Int!) {
article(where: {author_id: {_eq: $author}}) {
id
title
content
created_at
}
}
That's it! These are the only queries required to build this demo app. Now what about the routes? Well, it is actually pretty easy to write them. react-static reads a config file called static.config.js which can export a bunch of config options and getRoutes is one of them. It should resolve an array of route objects.
Our aim is to create a route for listing all authors and one route for listing all articles written by a given author. So we will have a /blog route which displays the list of authors and a /blog/:authorId route, which displays a list of all articles written by a particular author.
Now using the above GraphQL queries, we can write routes that cover the above use case. The code snippet for static.config.js looks something like this:
Notice that, we are importing the GraphQL queries defined to fetch authors and articles. In getRoutes, we are returning an array of routes constructed to match our routing requirement of /blog/:authorId.
We are mapping over each author to create a route for individual authors and returning the response of the GraphQL query to the react component. The response should ideally contain the list of articles for the given author. The templated markup is now constructed during build time and react-static outputs a bunch of HTML files, each for one of the above routes.
This can be used to create any kind of dynamic routing to suit your needs. We are using Apollo Client to make the GraphQL queries.
Final Thoughts
The idea of rendering static pages is to improve performance; time to first byte. With a CDN in front of these apps, scaling becomes much easier as you have to just cache and render the files in more regions. The developer experience is also better with more targeted development and debugging. GraphQL APIs and tooling make it more easier to build such apps.
I have put together a boilerplate and tutorial so that you can get started quickly!
Check it out on github .
Read more about JAMStack and documentation of react-static to play around with the app.