How To Make A Blog With React & GraphQL

I thought Rest was good, but GraphQL is amazing!

Sign up it’s free!

Step 1 — Setup GraphCMS:

GraphCMS Dashboard

Adding Fields:

Make sure to click “R” on the main Post model and Asset

Giving API access:

Creating Dummy Data:

Step 2 — Create New React Project:

npm i -g create-react-app
create-react-app blog
cd blog
npm i react-router-dom react-apollo graphql-tag apollo-client apollo-link-http apollo-cache-inmemory
npm start

Step 3 — Start Coding

Index.js

import React from 'react';import ReactDOM from 'react-dom';import { ApolloClient } from 'apollo-client';import { HttpLink } from 'apollo-link-http';import { InMemoryCache } from 'apollo-cache-inmemory';import { ApolloProvider } from 'react-apollo'import App from './App';import registerServiceWorker from './registerServiceWorker';
const API = 'ENTER_YOUR_API_ROUTE_HERE';
const client = new ApolloClient({ link: new HttpLink({ uri: API }), cache: new InMemoryCache()});ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>,document.getElementById('root'));registerServiceWorker();

Header Component

import React from 'react';
const Header = () => { return <header>Headless CMS</header>;}
export default Header;

Landing Component

import React from 'react';import { Link } from 'react-router-dom';import { graphql } from 'react-apollo';import gql from 'graphql-tag';const Landing = ({ data: { loading, allPosts } }) => { if (!loading) {  return (   <div className="wrapper">    {allPosts.map(post => (     <article className="content" key={post.id}>      <h2>{post.title}</h2>      <p dangerouslySetInnerHTML={{ __html: post.description }} />      <Link to={`/post/${post.slug}`}>       <button className="btn">Read More</button>      </Link>     </article>    ))}   </div>  ); } return <h2>Loading Posts...</h2>};const allPosts = gql` query allPosts {  allPosts {   id   title   description   slug  }}`;export default graphql(allPosts)(Landing);
//Landing.js<h2>Loading Posts...</h2>

Post Component

//Landing.js<Link to={`/post/${post.slug}`}>
<button className="btn">Read More</button>
</link>
import React from 'react';import { graphql } from 'react-apollo';import gql from 'graphql-tag';const Post = ({ data: { loading, post } }) => { if (!loading) {  return (   <article className="wrapper">    <div className="post">     <h1>{post.title}</h1>      <img src={post.image.url} alt="Dogs" />      <p dangerouslySetInnerHTML={{ __html: post.description }} />    </div>   </article>  ); } return <h2>Loading article...</h2>};const singlePost = gql` query singlePost($slug: String!) {  post: Post(slug: $slug) {    id    slug    title    description    image {     url    }   } }`;export default graphql(singlePost, { options: ({ match }) => ({  variables: {   slug: match.params.slug  } })})(Post);

App Component

import React  from 'react';import { BrowserRouter, Switch, Route } from 'react-router-dom';import Header from './Header';import Landing from './Landing';import Post from './Post';import './App.css';
const App = () => (<BrowserRouter> <main> <Header /> <Switch> <Route exact path="/" component={Landing} /> <Route path="/post/:slug" component={Post} /> </Switch> </main></BrowserRouter>);export default App;

Step 4 — Styling our App (Sort of)

* { box-sizing: border-box; padding: 0; margin: 0;}body { background-color: #F4F4F4;}header { height: 100px; background-color: rgb(211, 206, 206); display: flex; align-items: center; justify-content: center; font-size: 2.5em;}.wrapper { max-width: 1500px; margin: 0 auto;}/* Landing Section */.content { background-color: white; margin: 50px auto; padding: 1rem; box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.5);}article h2 { text-align: center;}article p { margin-top: 20px;}.btn { background-color: transparent; border: 1px solid black; padding: .5rem 1rem; margin: 20px auto 0 auto; display: block;}/* Post Section */.post { padding: 1rem;}.post h1 { text-align: center; margin: 20px;}.post img { display: block; margin: 0 auto 30px auto;}

Enjoy your React and GraphQL blog!

Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store