Build a Simple Blog with React, Next.js, and Cosmic.js GraphQL
This tutorial walks through creating a lightweight blog using React, Next.js, and Cosmic.js GraphQL, covering environment setup, dependency installation, package configuration, core component implementation, and sample GraphQL queries to fetch and display posts.
This article demonstrates how to build a basic blog system using React, Next.js, and Cosmic.js GraphQL.
Prerequisites
Ensure Node.js and npm are installed on your machine.
Setup
Create a project folder:
mkdir simple-react-blog
cd simple-react-blogAdd a package.json file with the required scripts and dependencies:
{
"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"
}
}Install the dependencies with npm i.
Core Component (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}") {
_id
type_slug
slug
title
metadata
created_at
}
}`
return await axios.post(`https://graphql.cosmicjs.com/v1`, { query })
.then(function (response) {
return {
cosmic: {
posts: _.filter(response.data.data.objects, { type_slug: 'posts' }),
global: _.keyBy(_.filter(response.data.data.objects, { type_slug: 'globals' }), 'slug')
}
}
})
.catch(function (error) {
console.log(error)
})
}
render() {
if (!this.props.cosmic) return <div>Loading...</div>
return (
<div>
<Header cosmic={this.props.cosmic} />
<main className="container">
{this.props.cosmic.posts && this.props.cosmic.posts.map(post => {
const friendly_date = helpers.friendlyDate(new Date(post.created_at))
post.friendly_date = friendly_date.month + ' ' + friendly_date.date
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></h2>
<div className="blog__author">
<a href={`/author/${post.metadata.author.slug}`}>
<div className="blog__author-image" style={{ backgroundImage: `url(${post.metadata.author.metafields[0].imgix_url}?w=100)` }}></div>
</a>
<div className="blog__author-title">by <a href={`/author/${post.metadata.author.slug}`}>{post.metadata.author.title}</a> on {post.friendly_date}</div>
</div>
<div className="clearfix"></div>
<div className="blog__teaser droid" dangerouslySetInnerHTML={{ __html: post.metadata.teaser }}></div>
<div className="blog__read-more"><a href={`/${post.slug}`}>Read more...</a></div>
</div>
</div>
)
})}
</main>
<Footer />
</div>
)
}
}Dependencies Overview
Axios – HTTP client for GraphQL communication.
Next.js – Universal React framework.
Next‑routes – Dynamic routing.
Express – Server‑side framework.
React – UI library.
Simple GraphQL Query Example
const gql_query = `{
objects(bucket_slug: "${config.bucket.slug}") {
type_slug
slug
title
content
metadata
created_at
}
}`
return await axios.post(`https://graphql.cosmicjs.com/v1`, { query: gql_query })
.then(function (response) {
return {
cosmic: {
posts: _.filter(response.data.data.objects, { type_slug: 'posts' }),
global: _.keyBy(_.filter(response.data.data.objects, { type_slug: 'globals' }), 'slug'),
post: _.find(response.data.data.objects, { slug: query.slug })
}
}
})
.catch(function (error) {
console.log(error)
})Conclusion
The complete source code is available on the Cosmic.js blog and GitHub, allowing you to download and customize the full blog, including dashboard components.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
