• Home
  • >
  • Tech News
  • >
  • Gatsby and Cosmic JS tutorial for building documentation – 2022

Gatsby and Cosmic JS tutorial for building documentation – is an article many of you are most interested in today !! Today, let’s InApps.net learn Gatsby and Cosmic JS tutorial for building documentation – in today’s post !

Read more about Gatsby and Cosmic JS tutorial for building documentation – at Wikipedia

You can find content about Gatsby and Cosmic JS tutorial for building documentation – from the Wikipedia website

Gatsby is an easy to use framework for generating static web site files.  It comes bundled with all sorts of hotness, like React JS for building web components. And GraphQL for handling our component state without the need to configure something like Redux to handle external data

Cosmic JS will handle our publishing and data storage.  It’s easy to set up and easy to implement for apps like this. Yet scalable enough to handle more complex projects across larger teams.  We will use this to create and store our documentation content.  This will us allowing us to focus on how our users interact with our app, and let Cosmic JS do all the heavy lifting.

Is that all?

Well no… we are going to convert our docs from markdown to html,  since that’s what web Browsers like.  To do this we are going to use a package called Showdown. that can handle parsing and converting markdown to and from HTML.

Any Requirements?

You will need to have access to a terminal, a Cosmic JS account with a bucket and a documentation object. The latest version of Node installed in order to install the necessary software to make this app work.  I’m going to be using yarn to run my build scripts but you can npm if you like.  Remember to choose npm or yarn and stick with it as things can get little hairy when it’s time to deploy.

Let’s Build!!

1.1 – Setting up our Development Environment

To get started we will want to install Gatsby and install our dependencies.  Easy peasy. Gatsby uses a handy command line interface (CLI) to build our initial project files.  First we will want to install the CLI by installing it globally with npm:

$ npm install -g gatsby-cli

This gives us access to the gatsby command and allows us to initialize our project.  Run the following script to create a new directory filled with a project template:

$ gatsby new gatsby-docs

Wait a second to allow the script to complete and you will notice a new directory created called gatsby-docs.   Let’s see what’s inside by changing directories:

$ cd gatsby-docs

Much of this will look familiar if are used to creating Node applications but some of this will be a little new. You should be able to get a development server up and running by executing the start script:

$ yarn start

After a second you should see a success prompt letting you know that everything has compiled properly and your app is live.

Now you can open up your browser pointing to localhost:8000 and see the compiled output.

Congrats! You have set up a working Gatsby site. But before we dig into what is going on under the covers let’s install the rest of our dependencies that will power our app:

$ yarn add cosmicjs showdown highlight.js dotenv node-sass gatsby-plugin-sass gatsby-source-graphql

Whoa… That’s a lot of newly installed packages, but each of these are super useful I swear.

  • cosmicjs will be used to add new content to our app.
  • showdown is the text parser I mentioned that will handle markdown and html conversion.
  • highlight.js is going to handle our syntax highlighting inside of our converted markdown text.
  • dotenv is an environment variable package that will make sure our sensitive tokens and/or runtime environment is configured from a .env file
  • node-sass and the gatsby-plugin-sass packages will allow to use .scss files to style our components.
  • gatsby-source-graphql will allow us to leverage GraphQL queries on external data (ie – use the Cosmic JS GraphQL api)

With all of that business out of the way. We can look at our directory and configure our Gatsby source code to run properly.

2.0 – Configuring Gatsby

Now we can dig into our directory and make sure Gatsby is configured properly. For using the technologies that will scalably and sensibly power our app.

The first file we will want to look into is gatsby-config.js.  This file is used to configure high level plugins, that allow source code to be bundled properly when static files built.  It also contains bit of metadata that describes our site to users and can be queried in our React Components.

Here we will add our newly installed plugins to the default configuration you see before you.  First we just need to add gatsby-plugin-sass to the plugins list, allowing us to import sass files and leverage sass to write sensible styling specs for each component.

Read More:   A CI/CD-Vendor Obsession – InApps Technology 2022

Next up we will add an object to end of our plugins list for gatsby-source-graphql  that will configure our external GraphQL API endpoint to allow us to fetch data from Cosmic JS.  Here’s how things should look:


module.exports = {
  siteMetadata: {
    title: `Gatsby Docs`,
    description: `Create and View Minimalistic Documentation, powered by GatsbyJs and CosmicJS`,
    author: `@jacobknaack`,
  },
  plugins: [
    `gatsby-plugin-eslint`,
    `gatsby-plugin-react-helmet`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-sass`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-docs`,
        short_name: `docs`,
        start_url: `/`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
    {
      resolve: `gatsby-source-graphql`,
      options: {
        url: `https://graphql.cosmicjs.com/v1`,
        fieldName: `docs`,
        typeName: `Doc`,
        refetchInterval: 10,
      },
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.app/offline
    // 'gatsby-plugin-offline',
  ],
}

Now we are set to make GraphQL queries to the Cosmic JS GraphQL API!  Next, Let’s talk for a second about Gatsby and how things are going to break down.

2.1 Building our app with Gatsby

I’ve mentioned that Gatsby is a static site generator, but what does that mean?  Gatsby takes all the fancy code we create and produces static files that are pre-configured using the config files we specify.  By doing so we get increased performance for sites that may have lots of images, data to be fetched, and other assets that can slow down web applications.

Let’s now get some source code created.  Our site is going to use just two ‘Pages’, one that will serve a home page to list the documentation we’ve created, and one for viewing a piece of documentation.  But to fetch the content that we are going to display, we are going to use GraphQL, which we have recently configured.  We will need to add some variables to our gatsby-node.js file in order to allow our static files to have the necessary parameters to make API calls.

Create a .env file and add your Cosmic JS environment variables

In your Cosmic JS Bucket > Basic Settings menu you will see fields for a bucket-slug and read and write keys down at the bottom.  Copy all three of these things and add them to a .env file.

At your project root, type into your terminal:

$ touch .env

Now Create three lines:

COSMIC_BUCKET=your-bucket-slug
COSMIC_READ_KEY=your-read-key
COSMIC_WRITE_KEY=your-write-key

We will use these with our dotenv package to allow our src files to access these variables when necessary.

Open up gatsby-node.js and add config variables to pages

We are now going to use Gatsby’s built in node API to give each page in our site access to the environment variable we just created.  First we will import the variables from our .env file using dotenv, then we will explicitly set each variable in our page’s context. Your file should look like this:

require("dotenv").config();
/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */
exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions

  deletePage(page)
  createPage({
    ...page,
    context: {
      writeKey: `${process.env.COSMIC_WRITE_KEY}`,
      readKey: `${process.env.COSMIC_READ_KEY}`,
      cosmicBucket: `${process.env.COSMIC_BUCKET}`
    }
  })
}

Creating our first page

Now we are going to create our first page that will grab all of the documentation objects and display them at the root of our site,  on index.js.  First let’s create our list by creating a folder in the components directory titled docs – /src/components/docs/ and in that folder we will create a file titled index.js.

This will be our module that is first displayed when we render our page after fetching our docs.  Here is the source code:


import React from 'react'import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'gatsby'

// formats our slugs to be used in links to our display page
function formatSlug(title) {
  return title
    .toLowerCase()
    .replace(/[^a-zA-Z ]/g, "")
    .replace(/s/g, '-')
}

// formats datestrings into an object so that they can
// easily be used for display
function formatDate(dateString) {
  const date = new Date(dateString)
  const months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December',
  ]
  const hh = date.getHours()
  let minutes = date.getMinutes()
  let hour = hh
  let dayTime="AM"
  if (hour >= 12) {
    hour = hh - 12
    dayTime="PM"
  }
  if (hour == 0) {
    hour = 12
  }

  minutes = minutes < 10 ? '0' + minutes : minutes

  return {
    year: date.getFullYear(),
    month: months[date.getMonth()],
    date: date.getDate(),
    hour: hour,
    minutes: minutes,
    dayTime: dayTime,
  }
}

const Docs = ({ docs }) => (
  <div className="docs-container">
    <div className="docs-list">
      {docs.map(doc => {
        const date_created = formatDate(doc.created_at)
        return (
          <Link
            key={doc._id}
            to={`/doc/${formatSlug(doc.title)}`}
            className="docs-item"
          >
            <div className="date-container">
              <h3 className="date-yearMonthDate">{`${date_created.month} ${
                date_created.date
                }, ${date_created.year}`}</h3>
              <p className="date-timeDayTime">{`at ${date_created.hour}:${
                date_created.minutes
                } ${date_created.dayTime}`}</p>
            </div>
            <h2 className="doc-title">{doc.title}</h2>
            <div
              className="doc-preview"
              dangerouslySetInnerHTML={{
                __html: doc.content,
              }}
            />
          </Link>
        )
      })}
    </div>
  </div>
)

Docs.propTypes = {
  docs: PropTypes.array.isRequired,
  pageContext: PropTypes.object,
}

export default Docs

What’s going on here:

This page basically runs a big loop over our docs  and returns some fancy jsx.  We map through the docs array and produce a Link from Gatsby that will contain the title, a date, and some content that uses a a description for the piece of documentation that was published.

Feel free to add any .scss files to this directory as well to get a styling that works for you for the given class names.

Update the ‘home’ page with our new components

Now we can open up our home page file at /pages/index.js and import the components we just created and add them to our returned jsx.


import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'

import Layout from '../components/layout'
import SEO from '../components/seo'
import Docs from '../components/docs'

const IndexPage = ({ data, pageContext }) => {
  return (
    <Layout>
      <SEO
        title="Home"
        keywords={[
          `gatsby`,
          `application`,
          `react`,
          'documentation',
          'docs',
          'markdown',
        ]}
      />
      <Docs docs={data.docs.objectsByType} pageContext={pageContext} />
    </Layout>
  )
}

IndexPage.propTypes = {
  data: PropTypes.object,
  pageContext: PropTypes.object,
}

export const query = graphql`
  query($cosmicBucket: String!, $readKey: String!) {
    docs {
      objectsByType(
        bucket_slug: $cosmicBucket
        type_slug: "docs"
        read_key: $readKey
      ) {
        title
        content
        created_at
        _id
      }
    }
  }
`

export default IndexPage

Now any docs created on Cosmic JS, will appear here on the home page!

Read More:   Update Microservices and Data with Vexata CTO Surya Varanasi

Notice the exported query at the bottom of the file.  It contains two string type variable that will be present because we set the context object in our gatsby-node configuration.

With our newly created home page working, let’s create our doc view that will display content from the documentation that we post.

Creating our doc display page

Instead of adding a new file to the pages directory in Gatsby, we are going to create a templates directory and make a template page that we can configure on build, so that each time a doc is created, a new page can be created when we fetch our Docs from Cosmic JS.

Start by creating a templates directory at your project root, and then creating a docPage.js file within `templates`

Now add the page template complete with exported query that will fetch a singular doc from Cosmic JS:


import React from 'react'
import showdown from 'showdown'
import PropTypes from 'prop-types'
import Layout from '../components/layout.js'
import SEO from '../components/seo.js'
import { graphql, Link } from 'gatsby'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'

const converter = new showdown.Converter({ ghCompatibleHeaderId: true })

class DocPage extends React.PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      Doc: props.data.docs.object,
    }
  }

  componentDidMount() {
    hljs.initHighlighting()
  }

  componentWillUnmount() {
    hljs.initHighlighting.called = false
  }

  render() {
    let toc
    let doc
    for (const i in this.state.Doc.metafields) {
      if (this.state.Doc.metafields[i].key === 'table_of_contents') {
        toc = this.state.Doc.metafields[i].value
      }
      if (this.state.Doc.metafields[i].key === 'documentation') { 
        doc = this.state.Doc.metafields[i].value
      }
    }
    return (
      <Layout selectedDoc={this.state.Doc}>
        <SEO
          title={this.state.Doc.title}
          keywords={[`${this.state.Doctitle}`, 'gatsby', 'documentation']}
        />
        <div className="doc-container">
          <div className="toc-container">
            <div className="back-bttn">
              <i className="arrow left" />
              <Link to="/">Back To List</Link>
            </div>
            <div
              className="doc-toc"
              dangerouslySetInnerHTML={{ __html: converter.makeHtml(toc) }}
            />
          </div>
          <div
            className="doc-main"
            dangerouslySetInnerHTML={{ __html: converter.makeHtml(doc) }}
          />
        </div>
      </Layout>
    )
  }
}

export const query = graphql`
  query($cosmicBucket: String!, $title: String!, $readKey: String!) {
    docs {
      object(bucket_slug: $cosmicBucket, slug: $title, read_key: $readKey) {
        title
        content
        created_at
        _id
        metafields {
          key
          value
        }
      }
    }
  }
`

DocPage.propTypes = {
  data: PropTypes.object.isRequired,
}

export default DocPage

Nothing will happen with this template until we tell Gatsby that it needs to create a page using this template. We do this so that Gatsby has a chance to fetch our Documentation from Cosmic JS before it builds the page using the necessary parameters for each GraphQL query at the bottom of docPage.js.  We are using static site files after all.

Update Gatsby Node to build template pages

Let’s go ahead and add an export function to gatsby-node.js so that we are building docPage template from our GraphQL data:


require("dotenv").config();
const path = require('path');
/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */
exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions

  deletePage(page)
  createPage({
    ...page,
    context: {
      writeKey: `${process.env.COSMIC_WRITE_KEY}`,
      readKey: `${process.env.COSMIC_READ_KEY}`,
      cosmicBucket: `${process.env.COSMIC_BUCKET}`
    }
  })
}

// Gatsby's built in createPages API lets you
//  explicitly create a page route from a template
exports.createPages = ({ graphql, actions }) => {
  const { createPage, createRedirect } = actions

  // configures our route and redirect slug
  createRedirect({
    fromPath: `/doc/*`,
    isPermanent: true,
    redirectInBrowser: true,
    toPath: `/`,
  })

  // This promise makes a graphql request and builds
  //  a page using the returned data and our docTemplate
  return new Promise((resolve, reject) => {
    const docTemplate = path.resolve(`src/templates/docPage.js`)

    resolve(
      graphql(`
        query {
          docs {
            objectsByType(bucket_slug: "${process.env.COSMIC_BUCKET}", type_slug: "docs", read_key: "${process.env.COSMIC_READ_KEY}") {
              title
            }
          }
        }
      `
      ).then(result => {
        if (result.errors) {
          reject(result.errors)
        }
        result.data.docs.objectsByType.forEach(doc => {
          let slug = doc.title.toLowerCase().replace(/s/g, '-')
          createPage({
            path: `/doc/${slug}`,
            component: docTemplate,
            context: {
              cosmicBucket: `${process.env.COSMIC_BUCKET}`,
              readKey: `${process.env.COSMIC_READ_KEY}`,
              title: slug,
            }
          })
        })
      })
    )
  })
}

Now when Gatsby creates its pages, ie – the index page will fetch our docs. Create page for each doc that is retrieve, and attaching all the necessary params to the page.  So our template component is render and our GraphQL query will succeed!

3.0 Deployment

Lastly we can talk about deployment and about how static sites work.  Deploying this bad boy can be a little tricky as this site uses a static build. It won’t have the necessary pages of newly created docs until the deployment service has a chance to rebuild.

My recommendation is to use netlify and link your source from GitHub or wherever you store your code.  From there you can trigger buildhooks in order to rebuild your site whenever certain events happen.  Cosmic JS allows a post request to be fired off at endpoint when objects are created, deleted, edited, etc.  So you can easily link the two together to make some magic happen.  Keep in mind, if you want to allow users to create Docs from within your UI. We will fire a POST request manually to activate a buildhook when a doc is successfully created.

Anyway, that’s all for me folks! Happy hacking.

Source: InApps.net

List of Keywords users find our article on Google:

wawa menu
gatsby tutorial
gatsby docs template
graphql jobs
node-sass
парсер hotline
hire graphql web developer
hire graphql developers
facebook graphql
seo js
graphql npm
seo beginners tutorial
react helmet gatsby
node sass npm
componentdidmount
gatsby templates
dotenv npm
prop types npm
graphql object type
node sass
gatsby documentation
metafields
hire gatsbyjs developers
node dotenv
graphql js
npm graphql
hire framer.js designers
eslint plugin import
gatsby plugins
peasy ai
gatsby template
graphql query array
whatsapp web js
seo wikipedia
next js with graphql
seo keywords tutorial
gatsby doc
npm classnames
npm dotenv
gatsby hair products
npm helmet
npm env
gatsby portfolio template
net core graphql
graphql tutorial java
super progressive web apps review
graphql and redux
graphql icon
cosmic digital design
redux graphql
graphql with redux
speedy generator hire
react native graphql
gatsby blog template
gatsby js graphql
graphql variables
react-markdown
hire graphql web developers
seo tutorial
props wikipedia
cosmic client
eslint-plugin-react
helmet npm
cosmic js
gatsby plugin
great gatsby prop hire
fetch recruitment
outsource el segundo
react native title
js firm
transformer table 3.0
graphql youtube
slugify npm
gatsby scss
fb graphql
graphql net core
react-native-dotenv
eslint import order
npm sass
gatsby styled components
eslint-plugin-promise
gatsby-plugin-sharp
net graphql
net graphql client
gatsby-plugin-react-helmet
gatsby source graphql
api platform data transformer
facebook game development tutorial
graphql with next js
deploy react app to netlify
graphqljs
graphql code generator
react native config
redux with graphql
hire markdown developers
js industries
type graphql
graphql react native
gatsby plugin sharp
react native env
graphql list
graphql java tutorial
localhost:8000
best gatsby tutorial
gatsby options
graphql redux
npm install node fetch
gatsby netlify
next js graphql
proptypes react
graphql state
react native yarn install
graphql data types
graphql update
gatsby node js
netlify config file
string js
highlight.js github
node-sass github
github gatsby
power apps documentation
createredirect gatsby
the manifest ecommerce seo
video.js npm
1024×1024 converter
export default as v1 from ‘./v1.js’
gatsby products
yourcode recruitment group
npm react markdown
wawa menue
power query m documentation
gatsby cli update
classnames npm
npm video js
npm markdown parser
j&s consultancy
eslint-plugin-import
react-helmet npm
front page design for project file
html-react-parser npm
import documentation jobs
gatsby-plugin-sass
knaack storage
react native dotenv
whatweb for whatsapp
gatsby-plugin-offline
npm helmet react
promise npm
request-promise npm
sharp npm
slug conversion
wikipedia leverage
magic card market api
pegas menu
custom vision api tutorial
gatsby netlify plugin
linkedin tutorial
video js documentation
business objects documentation
gatsby portfolio templates
npm node sass
npm rebuild node-sass yarn
web whatsapp js
gatsby cli
great gatsby actions
product metafields
sass npm
cosmic service center
node-saas
types/react
node red parse html
parser contenta node.js
state super sass
парсер для hh
eslint plugin react
hire scss developer
npm request promise
styled components gatsby
bad boy tutorial
cosmic break
create react app netlify
env touch 2
redux fetch data
gatsby-plugin-layout
graphql offline first
react get month from date
redux and graphql
scss npm
export company website template
node sass rebuild
react-native-config
the great gatsby mind map
парсер hh
cosmic names generator
deploy node app to netlify
gatsby js español
graphql net
r markdown template
telegram api js
парсеры для hh
graphql two types
helmet in node js
npm node-sass
slug menu
commerce.js
createsite.info
datadocs
eslint tutorial
graphql complex input type
import order eslint
learning gatsby online courses
gatsby create pages
gatsby plugin react helmet
gatsby-source-graphql
graphql facebook
how to deploy react app on netlify
netlify templates
npm node-fetch
react componentdidmount
resolve js
business objects tutorial
cosmic ordering service
create your own e-commerce store with react/redux admin/user
gatsby redux
graphql type
js lift
netlify backend
node js whatsapp message
npm run build if present
telegram api docs
api.whatsapp.com parameters
graphql input types
hire three.js developers
netlify npm version
power query relative path
react-query graphql
send whatsapp message using node js
парсер email facebook
eslint global variable
fb api documentation
j’s market menu
java constructor documentation
npm code highlighter
react foreach
react query vs redux
what happened to gatsby
yarn add
yarn rebuild node-sass
graball net
graphql fetch policy
graphql input type
markdown-it react
next-graphql-server
node red write file
node-fetch post
react admin documentation
resolve project file location
slug in node js
using react query with redux
jsx use variable in string
markdown handling team
next js and graphql
office addin manifest
webcomponents react
.env react
cosmic technologies
eslint import
eslint import-order
first page of project file
graphql-js
hairy root
hire gatsbyjs developer
how does tolowercase work java
metafields 2
node js get date
npm i sharp
power query m tutorial
react app env variables
react query graphql
redux gatsby
dotenv config
gatsby js ecommerce
gatsby js netlify
get term id by slug
graphql in react native
graphql syntax
great gatsby map
great gatsby props
java get month and year from date
net core 2.1 runtime
node js foreach
node js parser html
node js whatsapp
node js парсер
what does gatsby mean
yarn config file
custom vision documentation
how to create index.js file in terminal
netlify cli
node js dotenv
react markdown
react native loop through array
react-native config
custom vision api documentation
dot env node
dotenv cli
gatsby redirect
gatsby sharp
gatsby-node.js
graphql java
graphql types
java doc api
markdown react
minimal business card design
npm install sass
on touch js
pagecontext
react native export default
redux fetch
yarn config options
gatsby docs
gatsby fetch data from api
gatsby helmet
gatsby-transformer-sharp
graphql date
install node sass version 4
npm-sass
whatsapp business api docs
node send whatsapp message
foreach loop in react js
gatsby
index of /.env
seo outsourcing asia
seo tutorial for beginners
Rate this post
As a Senior Tech Enthusiast, I bring a decade of experience to the realm of tech writing, blending deep industry knowledge with a passion for storytelling. With expertise in software development to emerging tech trends like AI and IoT—my articles not only inform but also inspire. My journey in tech writing has been marked by a commitment to accuracy, clarity, and engaging storytelling, making me a trusted voice in the tech community.

Let’s create the next big thing together!

Coming together is a beginning. Keeping together is progress. Working together is success.

Let’s talk

Get a custom Proposal

Please fill in your information and your need to get a suitable solution.

    You need to enter your email to download

      [cf7sr-simple-recaptcha]

      Success. Downloading...