How to build a Headless website with Craft CMS and Gatsby.js
How to build a Headless website with Craft CMS and Gatsby.js

How to build a headless craft website

Since the release of Craft 3.3, which introduced ‘headless mode’ and GraphQL integration, building a headless craft website is now much more feasible. Going headless is becoming more desired for the flexibility, speed, and the security it adds to a website over a traditional CMS. GraphQL, which was developed by Facebook, is a query language for API’s and responds with all the requested content that can be manipulated and rendered in your Front-End Library of choice.

The first step in building a headless Craft CMS website is to create a GraphQL schema and generate a private token. In order to do this, navigate to GraphQL within Craft, and then into schemas where you name the schema, set its privacy, and can copy the generated token. Then create a .env file to hold these secrets:

GRAPHQL_TOKEN=[token]; GRAPHQL_URL=http://example.com/api;

Then the next step is to decide which Front-End Static Site Generator to use. A few examples of Static Site Generators which are all open-source are Nuxt.js (used with Vue), Next.js, and Gatsby.js This headless Craft tutorial will be going over how to integrate Gatsby.js, which is React-based, to our headless Craft CMS site. Gatsby.js is high-preformative and connects well with GraphQL.

Install Gatsby.js with:

npm install -g gatsby-cli;

Then create a new project: gatsby new project-name

Next, cd into that project and install the Gatsby’s GraphQL plugin:

npm install --save gatsby-source-craft;

Require the ‘dotenv’ package at the top of gatsby-config.js and add the source:

plugins: [ { resolve: 'gatsby-source-craft', options: { craftGqlToken: '${process.env.GRAPHQL_TOKEN}', craftGqlUrl: '${process.env.GRAPHQL_URL}' } ]

That’s all that is required for configuring a headless CMS website with Craft, GraphQL, and Gatsby.js! The next step is to create a query to pull data from your newly created API. A very general query that would just return the title of the site would be:

const data = useStaticQuery(graphql' query TitleQuery { site { siteMetadata { title } } } ')

useStaticQuery is the React-Hook form of <StaticQuery /> which we import from Gatsby. Static Queries can be used on data that won’t be dynamic, like the metadata of a site. Now that we have our query created, we can use it to fetch the title of our site. In our Index component (/src/components/index.js), we can display the title of our site like so:

import React from "react"; import { useStaticQuery, graphql } from "gatsby"; export default function Header() { const data = useStaticQuery(graphql' query TitleQuery { site { siteMetadata { title } } } ‘) return ( <header> <h1>{data.site.siteMetadata.title}</h1> </header> )}

Running `gatsby-develop` will start running the app on your local server at http://localhost:8000

And provide you with a second link http://localhost:8000/___graphql which can be used to test your queries on a local GraphQL server.

The initial site will look like this:

Craft CMS Gatsby JS Headless Starter
Craft CMS Gatsby JS Headless Starter

But with the ability to pull in all of your content from Craft, this default starter page can turn into anything! It was just that straightforward to create a headless Craft CMS website using React.js, GraphQL, and Gatsby.js. For how easy and painless setting up was, and all the other advantages going headless provides, there is not much reason not to!

selected projects
selected projects
selected projects
Big ideas. Bigger results. Let’s make it happen. Get an instant quote today.

sf-required

Manage recurring validation states.
sf-form_input
sf-required
Field Input (Required)
sf-form_checkbox-field
sf-required
Checkbox (Required)
sf-form_radio-field
sf-required
Radio (Required)
sf-form_input-select
sf-required
Select (Required)
sf-form_input-date
is-icon-left-right
sf-required
sf-form-icon-left
sf-required
Date Input (Required)
This is an error tag
sf-form_input-error-wrapper
sf-required
Error Tag (Required)
sf-form-icon-right
sf-required
Icon on Input Right (Required)
sf-form-icon-left
sf-required
Icon on Input Left (Required)
sf-form-icon-right
is-text-area
sf-required
Icon on Input Right Text Area (Required)

sf-checked

Manage recurring checked radio & checkboxes states.
sf-form_checkbox-field
sf-checked
Checkbox (Checked)
sf-form_radio-field
sf-checked
Radio (Checked)

sf-focus

Manage recurring focusing for button, radio and checkbox states.
sf-form_radio-field
sf-focus
Radio (Focused)
sf-form_checkbox-field
sf-focus
Checkbox (Focused)

sf-hide

Manage hidden states.
sf-skeleton
sf-hide
Loader Box (Currently Hidden)

sf-await

Manage awaiting states.
sf-button-child
sf-await
sf-button-await-child
sf-await
Awaiting Status of Buttons
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Step {Current Slide}/{Max Slides}

Project Details

Start by telling us about your project.
This field is empty
Enter a valid email
Select one option
Next Slide

Key Project Requirements

Tell us about the essential features and requirements for your project.
This field is empty
Select one option
Next Slide

Timeline & Budget

Tell us about your project's timeline and budget.
This field is empty
Select one option
Next Slide

Additional Information

Anything else you'd like to add?
This field is empty
Select one option
End
Thank you! Your submission has been received! A representative will be in touch within 24 hours.
Oops! Something went wrong while submitting the form.