Back-end CMS
Contenful can be used as a back-end content management system (CMS) for your front-end applications. In this tutorial I will show you how I have implemented contentful CMS with Gatsby js (a JavaScript front-end framework), together creating a full stack working app.
Starting with contentful and after signing up and logging in, I will add some content, images etc. this is setting up the back-end. Contentful is FREE so that’s great we’ll take advantage of there FREE tier, and there’s enough space for a project of your own. On the FREE tier you can have 2 environments with 24 content types and 5000 records, so that’s plenty to get yourself going with a couple of working project.
Getting Started with Contentful
First to get started is by creating and naming an environment, in the free tier you have the choice of 2. In this tutorial I will name mine (gatsby site), next go into the content model tab and name your content model (products) next we need to add some fields, in my example I will create 5 fields in my content model called (product):
- Title => will be a short text field
- Description => long text field
- Price => decimal number
- Slug => short text
- Image => media
Next navigate to the content tab and start adding products with the necessary fields you have created. Add a few products so we have something to show when we do our first API call. (I will create 3).
Creating an API key in Contentful
To create the API keys navigate to the settings tab and click on the API keys, here we can see the example api, but we will create a new key by clicking on the Add API key button top right of screen. Name this accordingly to your environment you named earlier. I named mine (gatsby-site). Here we will need the Space ID and the Content Delivery API – access token to use in gatsby’s front-end (save this to clipboard). We’ll add this in the plugin.
Configure Gatsby js for Fetching data from Contenful’s API
Create and open a new gatsby project then navigate to the working directory and we need to install the gatsby-source-contentful plugin
In your terminal shell
npm install --save gatsby-source-contentful
We then need to connect contentful within our gatsby application.
// add plugin
// In the gatsby-config.js
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `Your spaceID here`,
// Learn about environment variables: https://gatsby.dev/env-vars
accessToken: `Your Content Delivery API - access token`,
},
},
run gatsby develop to run your local server
graphQL Query in Gatsby JS
To test queries with graphQL in gatsby on your local server, visit http://localhost:8000/___graphql to access the grapgQL interface. Now that we have set up and connected the back-end, we can query contenful’s API as follows
// QUERY PRODUCTS FORM CONTENTFUL API
query MyQuery {
allContentfulProduct {
nodes {
title
price
slug
image {
fluid {
src
}
}
}
}
}
You should see the products fetched from graphQL’s interface as so
{
"data": {
"allContentfulProduct": {
"nodes": [
{
"title": "925 Sterling Silver Heart Drop ",
"price": 99.00,
"slug": "925-sterling-silver-heart-drop-necklace",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/5Ng7XOquYv7NIG7wVTelvC/82d96f0d78271d33e647f2c701354e53/heat-drop-small.png?w=800&q=50"
}
}
},
{
"title": "Silver Gem Diffuser",
"price": 89.00,
"slug": "silver-gem-diffuser",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/2cHuxHqEkcARivFXu5HjfA/c40db3521acd1d6ee6e3cb16ef5e5cba/Optimized-silver-cyrc.jpg?w=800&q=50"
}
}
},
{
"title": "Gold Diffuser",
"price": 149.00,
"slug": "gold-diffuser",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/6VRFoDAIuGTI0zjESp4QAE/724a5161a7c3c654757ba024580a73eb/Optimized-Ogold-locket.jpg?w=800&q=50"
}
}
}
]
}
}
}
Create a Gatsby Component
From the graphQL interface after we have made the query and fetched the data needed we can use the code exporter tab, using the Page query in the drop down menu we can copy the code to to quickly create a the component and see if everything is work as accepted.
Create a products component in src/pages/products.js and paste the code from the code exporter:
// src/pages/products.js
import React from "react"
import { graphql } from "gatsby"
const ProductComponent = ({ data }) => <pre>{JSON.stringify(data, null, 4)}</pre>
export const query = graphql`
{
allContentfulProduct {
nodes {
title
price
slug
image {
fluid {
src
}
}
}
}
}
`
export default ProductComponent
Next navigate to http://localhost:8000/products to see the list of objects returned in JSON format. This is just a quick test to make sure it’s all working.
// src/pages/products.js
{
"allContentfulProduct": {
"nodes": [
{
"title": "925 Sterling Silver Heart Drop ",
"price": 30,
"slug": "925-sterling-silver-heart-drop-necklace",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/5Ng7XOquYv7NIG7wVTelvC/82d96f0d78271d33e647f2c701354e53/heat-drop-small.png?w=800&q=50"
}
}
},
{
"title": "Silver Gem Diffuser",
"price": 39,
"slug": "silver-gem-diffuser",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/2cHuxHqEkcARivFXu5HjfA/c40db3521acd1d6ee6e3cb16ef5e5cba/Optimized-silver-cyrc.jpg?w=800&q=50"
}
}
},
{
"title": "Gold Diffuser",
"price": 35,
"slug": "gold-diffuser",
"image": {
"fluid": {
"src": "//images.ctfassets.net/aly865psq7x3/6VRFoDAIuGTI0zjESp4QAE/724a5161a7c3c654757ba024580a73eb/Optimized-Ogold-locket.jpg?w=800&q=50"
}
}
}
]
}
}
Now we want to display the list of objects and render them on the screen, to do this we need to do some destructuring and then cycle through the array (list).
Render graphQL queries in Gatsby js
Changing the function from displaying JSON to rendering out the objects
First with some JavaScript destructuring magic and then assign it a variable named products. (this will unpack the values from the array and add it to our variable)
This way it will keep our code much cleaner when calling the properties. For example: Instead of calling allContentfulProduct.nodes.products.title now we can just call product.title
// src/pages/products.js
const ProductComponent = ({ data }) => {
// destructuring the nodes array and store it in products variable
const {
allContentfulProduct: { nodes: products },
} = data
// checking what we have
console.log(products)
return (
<Layout>
<section className="ProductComponent">
// map through the list assign new variable called product
{products.map(product => {
return (
<article className="ProductContainer" key={product.id}>
<Image
className="ProductImg"
fluid={product.image.fluid}
alt={product.title}
/>
<h3 className="ProductTitle">{product.title}</h3>
<p>${product.price}.00</p>
<br />
<Link to={`/products/${product.slug}`}>more details </Link>
</article>
)
})}
</section>
</Layout>
)
}
Complete component src/pages/products.js
// CONTENTFUL API REQUESTS EXAMPLES
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import Image from "gatsby-image"
import { Link } from "gatsby"
const ProductComponent = ({ data }) => {
// destructuring the nodes array and store in products variable
const {
allContentfulProduct: { nodes: products },
} = data
// check
console.log(products)
return (
<Layout>
<section className="ProductComponent">
{products.map(product => {
return (
<article className="ProductContainer" key={product.id}>
<Image
className="ProductImg"
fluid={product.image.fluid}
alt={product.title}
/>
<h3 className="ProductTitle">{product.title}</h3>
<p>${product.price}.00</p>
<br />
<Link to={`/products/${product.slug}`}>more details </Link>
</article>
)
})}
</section>
</Layout>
)
}
// QUERY PRODUCTS FORM CONTENTFUL API
export const query = graphql`
{
allContentfulProduct {
nodes {
id
price
title
slug
image {
fluid {
...GatsbyContentfulFluid
}
}
}
}
}
`
export default ProductComponent
This will list out all your products you have from the contentful API on archive type page. In the next tutorial I will show you how to display a single product page when click on, to display all the fields.
Furthermore, we’ll learn how to create pages dynamically meaning every time you add a product in contentful it will automatically generate all the pages needed in your front-end.