Gatsby Quick start guide

Estimated duration: 10 minutes

This guide shows you how to connect Prepr to a Gatsby project to get data from Prepr CMS. You'll learn how to make a simple blog with Gatsby and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.

Blog site end result

If you want to skip ahead, clone the repository on GitHub (opens in a new tab) to run the demo locally.

Prerequisites

You need to have the following setup before you connect your Gatsby project to Prepr.

Create a simple Blog website with Gatsby and Prepr CMS

Create a new Gatsby project

The instructions below will guide you on how to create an empty Gatsby project for your blog app. If you have an existing Gatsby project then you can skip this step.

  1. Execute the command below to create a new Gatsby project.

    npm init gatsby

    Enter the options as shown in in the image below to create the prepr-gatsby project structure used in this guide.

    gatsby options

  2. When the project is successfully created, execute the commands below to go to the prepr-gatsby folder, the root directory of the project, and to start the project.

    cd prepr-gatsby
    npm run develop
  3. You should now be able to view your app on your localhost, for example, http://localhost:8000/.

  4. Open your Gatsby project with your preferred code editor.

  5. Go to the src/pages folder and replace the contents of the index.js file with the following code to display your blog:

    ./src/pages/index.js
    import * as React from "react"
     
    const IndexPage = () => {
      return (
        <main>
          <h1>
              My blog site
          </h1>
        </main>
      )
    }
     
    export default IndexPage
     
    export const Head = () => <title>My blog site</title>

You should now see something like the image below on your localhost.

Empty Gatsby blog site

Connect to Prepr

Set up a connection to Prepr to retrieve CMS data with GraphQL. The instructions below show you how to connect to Prepr directly from your project so that you can execute GraphQL queries to request data from the Prepr API.

  1. For this project we use the gatsby-source-graphql data layer to connect to Prepr. Stop the server you started in the above step (CTRL-C) and execute the following command in the terminal to install the data layer:

    npm install gatsby-source-graphql
  2. We recommend using environment variables to store sensitive information like access tokens. To add environment variables, create a .env file in the root directory of your project and add the API URL as follows:

    ./.env
    PREPR_GRAPHQL_URL=<YOUR-PREPR-API-URL>
  3. Replace the placeholder value <YOUR-PREPR-API-URL> with the API URL of an access token from Prepr. This URL includes the access token for the environment you want to query from. Get this URL by logging into your Prepr account:
    a. Go to Settings → Access tokens to view all the access tokens.
    b. Copy the API URL value from the GraphQL Production access token to only retrieve published content items.

    access token

    Use the GraphQL Production API URL to request published content items for your live app and use the GraphQL Preview value to make a preview of unpublished content items for your content editors.

  4. Add a plugin for the Gatsby data layer and make the .env file visible to the project by updating the gatsby-config.js file with the following configuration:

    ./gatsby-config.js
    /**
    * @type {import('gatsby').GatsbyConfig}
    */
     
    // Make the .env file available to the project
    require("dotenv").config({
      path: `.env`,
    })
     
    module.exports = {
      siteMetadata: {
        title: `My blog site`,
        siteUrl: `https://www.yourdomain.tld`,
      },
     
      // Include a plugin for the Gatsby data layer 
      plugins: [
        {
          resolve: "gatsby-source-graphql",
          options: {
            typeName: "Prepr",
            fieldName: "prepr",
            url: process.env.PREPR_GRAPHQL_URL,
          }
        }
      ],
    }

The next step is to fetch content from Prepr using the Gatsby data layer.

Fetch multiple blog posts

Now that your app is connected to Prepr, fetch the blog posts from Prepr.

  1. Go to the src/pages folder and update the index.js to add a query to retrieve all blog posts and display them in the front end.

    ./src/pages/index.js
    import * as React from "react"
    import {graphql, useStaticQuery} from "gatsby";
     
    const IndexPage = () => {
      const preprData = useStaticQuery(graphql`
        query {
          prepr {
            Posts {
              items {
                _id
                _slug
                title
              }
            }
          }
        }
      `)
     
      const posts = preprData.prepr.Posts
     
      return (
        <main>
          <h1>
            My blog site
          </h1>
          <ul>
            {posts.items.map(posts => (
              <li key={posts._id}>
                <a href={posts._slug}>{posts.title}</a>
              </li>
            ))}
          </ul>
        </main>
      )
    }
     
    export default IndexPage
     
    export const Head = () => <title>Home Page</title>

You can create and test GraphQL queries using the Apollo explorer (opens in a new tab) from Prepr. Open the API Explorer from the Post content item page in Prepr or the access token page.

If you’re using preloaded demo data in your Prepr CMS environment as mentioned above in the Prerequisites section, you should have a few published blog posts as shown in the below image. The query will retrieve the ID, Slug, and Title of each blog post.

demo blog posts

Rerun the server with the command below. If your app runs without errors, then the setup above was done correctly.

npm run develop

Now when you view the website on your localhost, you'll see something like the image below.

Blog site - list of posts

Fetch individual blog posts

Now you have the list of blog posts with links to them. When a visitor clicks a blog post link, your app should open a detailed post page automatically. However, we haven't created the detailed page yet. Now, when you click the link, a new page opens with the slug in the URL, but a Page 404 error is displayed.

The instructions below show you how to set up the routing from the main page to the detailed page and how to fetch the blog post details based on the slug of the blog post that was clicked.

  1. Go to the src folder and create a new subfolder called templates. In this folder create the post.js page with the query to retrieve a specific blog post by its slug.

    ./src/templates/post.js
    import * as React from "react"
    import {graphql} from "gatsby";
     
    const PostPage = ({data}) => {
      const post = data.prepr.Post
      return (
        <main>
            <h1>
                {post.title}
            </h1>
            <div className="my-10" key={post?.cover.url} alt="{post.title}">
              <img
                  src={post?.cover.url}
              />
            </div>
            {post.content.map((content,index) => (
                <div key={index}>
        
                {
                    content.__typename === "Prepr_Assets" &&
                    <img src={content.items[0].url} width="300" height="250" alt="{post.title}" />
                }
        
                {
                    content.__typename === 'Prepr_Text' &&
                    <div dangerouslySetInnerHTML={{ __html: content.body }}></div>
                }
                </div>
            ))}
        </main>
      )
    }
     
    export const query = graphql`
      query($slug: String!) {
        prepr {
          Post (slug: $slug) {
            _id
            title
            cover {
              url(width: 300, height: 250)
            }
            content {
              __typename
              ... on Prepr_Text {
                _id
                body
                text
              }
              ... on Prepr_Assets {
                items {
                  _id
                  url(width: 300, height: 250)
                }
              }
            }
          }
        }
      }
    `
     
    export default PostPage
     
    export const Head = () => <title>Post Page</title>

Now that the query is added, fetch the individual blog post by its slug. Fetch the blog post title and the content.

The Post content is stored in a Dynamic content field. Check out the GraphQL docs for more details on how to fetch the data within this field.

Gatsby source plugin behavior

In the ./gatsby-config.js configuration, you set a prefix, Prepr, for each of the typename values to distinguish between multiple sources. Don't forget to remove these prefixes when testing these queries directly in Prepr through the Apollo explorer (opens in a new tab).

  1. Go to the root directory and create a new config file called gatsby-node.js. Add the following configuration to this file to define dynamic pages for each blog post:

    ./gatsby-node.js
    // Retrieve the blog post slug to create dynamic pages
    exports.createPages = async ({ actions, graphql }) => {
      const { data } = await graphql(`
        query {
          prepr {
            Posts {
              items {
                _slug
              }
            }
          }
        }
      `)
      data.prepr.Posts.items.forEach( (item) => {
        const slug = item._slug
        actions.createPage({
          path: slug,
          component: require.resolve(`./src/templates/post.js`),
          context: { slug },
        })
      })
    }

    Stop the server you started before (CTRL-C) and execute the command below in the terminal. If your app runs without errors, then the setup above was done correctly.

    npm run develop

Now, when you view your site, you can click a blog post link to direct you to that specific blog post like in the image below.

Gatsby blog site - detailed post page

All done

Congratulations! You have successfully connected a Gatsby project to Prepr for a simple Blog app.

Next steps

To learn more on how to expand your project, check out the following resources:

Was this article helpful?

We’d love to learn from your feedback