Strapi Getting Started with Gatsby

Strapi Getting Started with Gatsby

We all know that a headless CMS can deliver your content through an API directly to where you need it. Because of the headless approach the content can be used on any platform and technology you can think of, and is therefore a powerful option for mobile and web developers.

In this article we'll cover the integration and querying data using Strapi as a headless CMS to handle the backend and Gatsby for the front end. Before jumping to how to integrate Strapi with Gatsby, let’s first understand what Strapi is?

What is Strapi?

Strapi is a free and open-source headless CMS delivering your content anywhere you need.

  • Keep control over your data. With Strapi, you know where your data is stored, and you keep full control at all times.
  • Self-hosted. You can host and scale Strapi projects the way you want. You can choose any hosting platform you want: AWS, Render, Netlify, Heroku, a VPS, or a dedicated server. You can scale as you grow, 100% independent.
  • Database agnostic. You can choose the database you prefer. Strapi works with SQL & NoSQL databases: MongoDB, PostgreSQL, MySQL, MariaDB, and SQLite.
  • Customizable. You can quickly build your logic by fully customizing APIs, routes, or plugins to fit your needs perfectly.

You can easily retrieve data via GraphQL by adding it from Strapi plugins.

Why Strapi + Gatsby?

Using a static site generator brings a lot of advantages: Performance, security, lower cost of scaling but also an excellent developer experience. Gatsby brings enormous benefits to content creators and developers by solving many of the challenges with the headless approach.

Strapi provides a perfect solution as a source for Gatsby’s static markup generation. Whether building a static site or a more dynamic app/website Strapi has you covered with its flexibility of content types, plugins, and customization. Chris, GatsbyJS developer.

Let’s make this in action by building a blog using Gatsby and Strapi as a headless CMS.

Install Strapi and Create a new project

yarn create strapi-app my-project --quickstart

Create an Administrator user

Navigate to http://localhost:1337/admin

Complete the form to create the first Administrator user. Now you can create the content types you need. Once the installation is completed, you can start on your frontend.

Create a Gatsby site

Create a basic Gatsby site using the Gatsby CLI

gatsby new gatsby-app

You need to configure Gatsby to communicate with your Strapi.

yarn add gatsby-source-strapi

Add the gatsby-source-strapi to the plugins section in the gatsby-config.js file:

{
  resolve: "gatsby-source-strapi",
  options: {
    apiURL: "http://localhost:1337",
// list of the content type you created on Strapi, Ex:
   contentTypes:
[ "post", "category", "author" ],
// If using single types place them in this array.
// singleTypes: [`home-page`, `contact`],
    queryLimit: 1000,
  },
},

Now you can send requests to Strapi to fetch all the data you want from the content types.

Be sure that you activated the find, findOne permission for the content type. Lets use the content types we declare in the gatsby-config.js

  • Post
  • Category
  • Author

Example Request:

query {
  allStrapiPost {
    edges {
      node {
        id
        title
        content
      }
    }
  }
}

Since you can send requests to Strapi, let's generate pages for each of the posts, categories, and authors. We'll use the createPages API.

In createPages add the following code to your gatsby.node.js file:

exports.createPages = ({ actions, graphql }) => {
     const { createPage } = actions
graphql(`
        {
            allStrapiPost {
              edges {
                node {
                    id
                    title
                }
              }
            }
        }
        `
    ).then(({ data, errors }) => {
        if (errors) {
            return Promise.reject(errors)
        }

        const { edges } = data.allStrapiPost

        edges.forEach(({ node }) => {
            createPage({
                path: `/posts/${node.title}`,
                component: path.resolve(`./src/templates/post.js`),
                context: {
                    id: node.id,
                },
            })
        })
    })
graphql(`
        {
            allStrapiCategory {
              edges {
                node {
                    id
                    name
                }
              }
            }
        }
        `
    ).then(({ data, errors }) => {
        if (errors) {
            return Promise.reject(errors)
        }

        const { edges } = data.allStrapiCategory

        edges.forEach(({ node }) => {
            createPage({
                path: `/categories/${node.name}`,
                component: path.resolve(`./src/templates/category.js`),
                context: {
                    id: node.id,
                },
            })
        })
    })
graphql(`
        {
            allStrapiAuthor {
              edges {
                node {
                    id
                    name
                }
              }
            }
        }
        `
    ).then(({ data, errors }) => {
        if (errors) {
            return Promise.reject(errors)
        }

        const { edges } = data.allStrapiAuthor

        edges.forEach(({ node }) => {
            createPage({
                path: `/authors/${node.name}`,
                component: path.resolve(`./src/templates/author.js`),
                context: {
                    id: node.id,
                },
            })
        })
    })

    })
}

We are fetching all posts, authors, and categories to generate pages for each of them.

Create a ./src/templates/post.js file that will display the content of each one of your post:

import React from 'react'
import { graphql } from 'gatsby'

export const query = graphql`
  query Post($name: String!) {
    posts: strapiPost(title: { eq: $title }) {
      id
      name
      content
      category {
        id
        name
      }
      author {
        id
        name
      }
    }
  }
`

const Post = ({ data }) => {
  const posts = data.posts
  const category = data.posts.category
  const author = data.posts.author

  return (
    <div>
      <h1>{post.title}</h1>
      <ul>
        <li>{category.name}</li>
        <li>{author.name}</li>
      </ul>
      <p>{post.content}</p>
    </div>
  )
}

export default Post

You can find your post posts by browsing:

http://localhost:8000/posts/title-of-post.

Create a ./src/templates/category.js file that will display the content of each one of your category:

import React from 'react';
import { graphql, Link } from 'gatsby';

export const query = graphql`
  query Category($name: String!) {
    category: strapiCategory(name: { eq: $name }) {
      name
      posts {
        id
        name
      }
    }
  }
`;

const Category = ({ data }) => {
  const posts = data.category.posts;
  const category = data.category.name;

  return (
    <div>
      <h1>{category}</h1>
      <ul>
        {posts.map(post => {
          return (
      <Link to={`/posts/${post.title}`} />{post.title}</Link>
)
        })}
      </ul>
    </div>
  );
};

export default Category;

You can find your restaurant categories by browsing: http://localhost:8000/category/name-of-category.

Feel free to do the same for your authors!

Awesome! You can see the posts, and they are listed depending on the category and the author now.

Oussama Benidir
Oussama Benidir
2021-03-17 | 5 min read
Share article

More articles