In this tutorial, I’m going to show you how to create a simple but blazing fast blog using React, , and . Let’s get started. Gatsby JS Cosmic JS TL;DR Download the GitHub repo. Check out the demo. Prerequisites You will be required to install Node JS, npm, and Gastby CLI before starting. Make sure you already have them installed. What is Gatsby? is a blazing-fast website framework for React. It allows developers to build React based websites within minutes. Whether you want to develop a blog or a business website, Gatsby will be a good option. Gatsby Because it is based on React, the website pages are never reloaded and also it will generate static pages which make the generated website super fast. Blog Development We have to set up the environment in order to start working on the blog. Install Gatsby First, install Gatsby CLI: install -- gatsby-cli npm global Scaffold a Gatsby Template gatsby gatsby-blog-cosmicjs new Enter in your project’s folder: gatsby-blog-cosmicjs cd Start the server: gatsby develop At this point, you should already be able to get access to your Gatsby JS blog website at this address: . http://localhost:8000 Install the Cosmic JS Source Plugin In Static Blog, your data can be consumed from different sources: Markdown files, HTML files, External API (WordPress, Cosmic JS, etc). Therefore, Gatsby implemented independent layer: the data layer. Which is powered by GraphQL. Very exciting stuff! To connect this Data Layer with different Data Providers, you need to integrate Source Plugin. Fortunately, there are many Source Plugins available to fulfil most of the needs. In our case, we are using . Obviously, we need to integrate Source Plugin for Cosmic JS. Good news: Cosmic JS has implemented their ! Cosmic JS Source Plugin Let’s install: npm install --save gatsby-source-cosmicjs We need to install some other plugins also. Let’s do that also npm install --save gatsby-plugin-offline gatsby-source-filesystem These plugins need some configurations. So, replace the content of with: gatsby-config.js Path: gatsby-config.js .exports = { : [ , , { : , : { : , : , }, }, { : , : { : , objectTypes: [ , ], apiAccess: { : , } } }, ], } module plugins `gatsby-plugin-offline` `gatsby-plugin-react-helmet` resolve `gatsby-source-filesystem` options path ` /src/pages` ${__dirname} name 'pages' resolve 'gatsby-source-cosmicjs' options bucketSlug 'gatsby-blog-cosmic-js' // Bucket Slug 'posts' 'settings' // List of the Object Types you want to be able to request from Gatsby. read_key '' Then, restart the server to let Gatsby consider these updates. Posts List & Settings First, we want to display the list of posts on the homepage. To do so, add the following content to the existing homepage file: Path: src/pages/index.js React Link get Helmet Bio { rhythm } render() { siteTitle = get( , ) posts = get( , ) author = get( , ) ( <div> <Helmet title={siteTitle} /> <Bio settings={author}/> {posts.map(({ node }) => { title = get(node, ) || node.slug ( <div key={node.slug}> <h3 style={{ marginBottom: rhythm( / ), }} > <Link style={{ boxShadow: }} ={`posts/${node.slug}`}> {title} </Link> </h3> <small>{node.created}</small> <p dangerouslySetInnerHTML={{ __html: node.metadata.description }} /> </div> ) })} </div> ) } } BlogIndex pageQuery = graphql` query IndexQuery { allCosmicjsPosts(sort: { fields: [created], order: DESC }, limit: ) { edges { node { metadata{ description } slug title created(formatString: ) } } } cosmicjsSettings(slug: {eq: }){ metadata{ site_title author_name author_bio author_avatar { imgix_url } } } } ` import from 'react' import from 'gatsby-link' import from 'lodash/get' import from 'react-helmet' import from '../components/Bio' import from '../utils/typography' . { class BlogIndex extends React Component const this 'props.data.cosmicjsSettings.metadata.site_title' const this 'props.data.allCosmicjsPosts.edges' const this 'props.data.cosmicjsSettings.metadata' return const 'title' return 1 4 'none' to export default export const 1000 "DD MMMM, YYYY" "general" Explanation: At the end of file, we exported pageQuery. These are GraphQl queries which are used to fetch important information about settings and list of posts. index.js Then, we pass the destructed object as parameter of and loop on its & object to display the data. { data } IndexPage allCosmicjsPosts cosmicjsSettings Single Post Layout Till now we have integrated Cosmic JS source plugin with Gatsby and it’s look like a Blog. Now we will work on blog post’s details page. Let’s create the template: Path: src/templates/blog-post.js React Helmet Link get Bio { rhythm, scale } { relative } ; render() { post = .props.data.cosmicjsPosts siteTitle = get( .props, ) author = get( , ) { previous, next } = .props.pathContext ( <div> <style>{` .post-content { text-align: justify; } .post-hero { width: calc( % + ${rhythm( )}); margin-left: ${rhythm(- )}; height: ${rhythm( )}; } @media (max-width: ${rhythm( )}) { .post-hero { width: calc( % + ${rhythm(( / ) * )}); margin-left: ${rhythm(- / )}; height: ${rhythm( )}; } } `} </style> <Helmet title={`${post.title} | ${siteTitle}`} /> <div style={{ marginTop: rhythm( ), }} > <Link = > ← Back Posts </Link> </div> <h1 style={{ marginTop: rhythm( ), }} > {post.title} </h1> <p style={{ ...scale(- / ), display: , marginBottom: rhythm( ), marginTop: rhythm(- ), }} > {post.created} </p> <div className= style={{ backgroundColor: , backgroundImage: `url( )`, backgroundSize: , backgroundPosition: , marginBottom: rhythm( ), position: , }} ></div> <div className= dangerouslySetInnerHTML={{ __html: post.content }} /> <hr style={{ marginBottom: rhythm( ), }} /> <Bio settings={author} /> <ul style={{ display: , flexWrap: , justifyContent: , listStyle: , padding: , }} > {previous && ( <li> <Link ={previous.slug} rel= > ← {previous.title} </Link> </li> )} {next && ( <li> <Link ={next.slug} rel= > {next.title} → </Link> </li> )} </ul> </div> ) } } BlogPostTemplate pageQuery = graphql` query BlogPostBySlug($slug: String!) { cosmicjsPosts(slug: { eq: $slug }) { id content title created(formatString: ) metadata{ hero{ imgix_url } } } cosmicjsSettings(slug: {eq: }){ metadata{ site_title author_name author_bio author_avatar { imgix_url } } } } ` import from 'react' import from 'react-helmet' import from 'gatsby-link' import from 'lodash/get' import from '../components/Bio' import from '../utils/typography' import from 'path' . { class BlogPostTemplate extends React Component const this const this 'data.cosmicjsSettings.metadata.site_title' const this 'props.data.cosmicjsSettings.metadata' const this return 100 8 4 18 32 100 3 4 2 3 4 13 1.4 to "/" to 1 1 5 'block' 0.6 0.6 "post-hero" "#007ACC" "${post.metadata.hero.imgix_url}?w=2000" 'cover' 'center' 0.6 'relative' "post-content" 1 'flex' 'wrap' 'space-between' 'none' 0 to "prev" to "next" export default export const "MMMM DD, YYYY" "general" That looks fine, but at this point, Gatsby does not know when this template should be displayed. Each post needs a specific URL. So, we are going to inform Gatsby about the new URLs we need thanks to the createPage function. Path: gatsby-node.js _ = ( ) = ( ) path = ( ) exports.createPages = { { createPage } = boundActionCreators indexPage = path.resolve( ) createPage({ : , : indexPage, }) ( { blogPost = path.resolve( ) resolve( graphql( ).then( { (result.errors) { .log(result.errors) reject(result.errors) } posts = result.data.allCosmicjsPosts.edges; _.each(posts, (post, index) => { next = index === posts.length - ? : posts[index + ].node; previous = index === ? : posts[index - ].node; createPage({ : , : blogPost, : { : post.node.slug, previous, next, }, }) }) }) ) }) } const require 'lodash' const Promise require 'bluebird' const require 'path' ( ) => { graphql, boundActionCreators } const const './src/pages/index.js' path `posts` component return new Promise ( ) => resolve, reject const './src/templates/blog-post.js' ` { allCosmicjsPosts(sort: { fields: [created], order: DESC }, limit: 1000) { edges { node { slug, title } } } } ` => result if console // Create blog posts pages. const const 1 null 1 const 0 null 1 path `posts/ ` ${post.node.slug} component context slug Restart the Gatsby server. From now on, you should be able to visit the detail page by clicking on URLs displayed on the homepage. Extra Stuff! In addition to this, We also implemented to display Author information & to create a generic layout for the blog. src/components/Bio.js src/layouts/index.js The . To see it live, clone the repository, and run ( ). source code is available on GitHub cd gatsby-blog-cosmicjs && npm i && npm run develop Finally, restart the server and visit the website. It will look awesome! The static website generated by Gatsby can : Netlify, S3/Cloudfront, GitHub pages, GitLab pages, Heroku, etc. easily be published on storage providers Our is deployed on Netlify. Note: demo Conclusion Congrats! You’ve successfully built a super fast and easy-to-maintain blog! Feel free to continue this project to discover both Gatsby and Cosmic JS advantages.