How to Build a Simple Blog Using React and GraphQL

This article was sponsored by Cosmic JS. Thank you for supporting the partners who make SitePoint possible.
In this tutorial I’m going to show you how to create a simple blog using React, GraphQL and Cosmic JS. This is going to be the fastest and most light-weight blog built on a modern technology stack. Let’s get started.
View the demo
Install the Simple React Blog on Cosmic JS
View the codebase on GitHub

Getting Started
Make sure that you have Node.js and NPM installed on your machine, if not, visit the Node.js website to install the latest version.
Let’s start by creating a folder for our app. In your favorite terminal run the following commands:
mkdir simple-react-blog
cd simple-react-blog

Now let’s add a package.json file to import all of our dependencies for our app:
vim package.json

Add the following to our package.json file:
“scripts": {
"dev": "node server.js",
"build": "next build",
"start": "next build; NODE_ENV=production node server.js"
"dependencies": {
"axios": "^0.16.2",
"express": "^4.16.2",
"lodash": "^4.17.4",
"next": "^4.0.3",
"next-routes": "^1.1.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"

It’s a pretty light dependency list for a pretty light app. So what we will install is:

Axios for our promise-based HTTP client to get content from to the Cosmic JS GraphQL API.
Next.js as our React Universal framework.
Next routes for dynamic routes.
Express for our server-side web app framework.
React to handle our user interface.

Our scripts are necessary for starting our app in production and development.
Run the following command to install our dependencies:
npm i

Building Our Blog
Next, let’s begin building our blog pages. Create a pages folder and add the index.js file:
vim index.js

and add the following to index.js:
import axios from ‘axios’
import _ from ‘lodash’
import Footer from ‘./partials/footer’
import Header from ‘./partials/header’
import helpers from ‘../helpers’
import config from ‘../config’

export default class extends React.Component {
static async getInitialProps({ req }) {
const query = `{
objects(bucket_slug: "${config.bucket.slug}") {
return await``, { query })
.then(function (response) {
return {
cosmic: {
posts: _.filter(, { type_slug: ‘posts’ }),
global: _.keyBy(_.filter(, { type_slug: ‘globals’ }), ‘slug’)
.catch(function (error) {
render() {
if (!this.props.cosmic)

return (
<Header cosmic={ this.props.cosmic }/>
<main className="container">
this.props.cosmic.posts && => {
const friendly_date = helpers.friendlyDate(new Date(post.created_at))
post.friendly_date = friendly_date.month + ‘ ‘ +
return (
<div className="card" data-href={`/${post.slug}`} key={post._id}>
post.metadata.hero.imgix_url &&
<a href={`/${post.slug}`} className="blog-post-hero blog-post-hero–short" style={{ backgroundImage: `url(${post.metadata.hero.imgix_url})`}}></a>
<div className="card-padding">
<h2 className="blog__title blog__title–small">
<a href={`/${post.slug}`}>{post.title}</a>
<div className="blog__author">
<a href={`/author/${}`}>
<div className="blog__author-image" style={{ backgroundImage: `url(${[0].imgix_url}?w=100)`}}></div>
<div className="blog__author-title">by <a href={`/author/${}`}>{}</a> on {post.friendly_date}</div>
<div className="clearfix"></div>
<div className="blog__teaser droid" dangerouslySetInnerHTML=></div>
<div className="blog__read-more">
<a href={`/${post.slug}`}>Read more…</a>
<Footer />

Continue reading %How to Build a Simple Blog Using React and GraphQL%