Building a Blog with React, Strapi & GraphQL - Create Post & Display it in Frontend

Hey there, this is the second part of the mini series in Building an app with React, Strapi, and GraphQL. In the first part that you can find here, we went through first steps in prepping the backend and frontend for our app.
In this part we will go through creating a blog post and displaying it in the list.

Add Blog Post to the Strapi

First of all, spin up your Strapi environment with the command in the terminal from the directory that houses Strapi:

$ yarn develop

This will start the Strapi server so you can now navigate to http://localhost:1337/admin/, once you are there enter the login data for the admin user.
Now in the left sidebar, chose Content-Types Builder and this will bring you to the list of your content type so click Create Content Type.
As a name enter BlogPost and press Continue, next you will be prompted to select a field for our content type:
Strapi content type fields

For a proper Blog post we need following fields:

  • Title (Text - Short text)
  • Body (Text - Long text)
  • Tags (Text- Short text)
  • CreatedAt (Date - datetime)

Go on and create those fields by selecting the type from the parentheses. Don't forget to click save after you have added them.

Add a Blog post

In this case we will also use our Strapi backend. Make sure that the Strapi server is running and navigate to http://localhost:1337.
In the collection type section of the left sidebar under Collection Types click on BlogPosts. This will open a list of current BlogPosts with the button to add a new Blog post, press that button to add a new Blog post.
Fill out all the fields as you like and click Save and after that click Publish.
Now when you click on Collection Types BlogPosts you will see our new post in the list.
Next we will show the list of blog posts in the frontend of our application.

Show the list of blog posts in frontend

If you followed steps from the first part in frontend folder we have everything ready to fetch the data from the Strapi backend.
In the frontend folder create a new directory under src named queries there create a new file named blogPosts.js.
In this file we will write a GraphQL query that will fetch us needed data from Strapi.

frontend/src/queries/blogPosts.js

import { gql } from '@apollo/client'

export const GET_BLOGPOSTS = gql`
  query {
  blogPosts {
    id
    Title
    Body
    Tags
    CreatedAt
  }
}`

You can test queries by navigating to http://localhost:1337/graphql

Now we need to write a component that will call this query and populate our table with the data, so let's create a ListBlogPosts.js inside frontend/src/components

frontend/src/components/ListBlogPosts.js

import React from 'react'
import { GET_BLOGPOSTS } from "../queries/blogPosts"
import {useQuery} from "@apollo/client";

function ListBlogPosts() {

    const {data, error, loading} = useQuery(GET_BLOGPOSTS)

    if(loading) return 'Loading...'
    if(error) return `Oops there has been an error: ${error}`
    if(data) return console.log(data)
}

export default ListBlogPosts

We will use this to test whether our query actually works!
If you save this, run the server with yarn start and navigate to http://localhost:3000 you will see ..this:

Oops there has been an error: Error: Forbidden

And that is OK! It shows that our connection with Strapi works, that our basic error handler works because we are forbidden to read this data so this is Strapi issue.
Let's go back to Strapi backend and fix this, open Strapi backend and go to Settings and under Users & Permissions Plugin section select Roles. There you will see our BLOG-POSTS with all checkboxes deactivated, use select all to check all boxes and save it.
Now when you refresh http://localhost:3000 you will see nothing but when you open console you will see we get the object. Success! Now let's show that in a way we humans understand it. Remove the line with if(data)... and create this return instead:

frontend/src/components/ListBlogPosts.js

...
if(error) return `Oops there has been an error: ${error}`

return(
        <div>
            <h1>List of Blog Posts</h1>
            <table>
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Title</th>
                        <th>Body</th>
                        <th>Tags</th>
                        <th>Created</th>
                    </tr>
                </thead>
                {data?.blogPosts && data?.blogPosts.length !== 0 ?
                    <tbody>
                    {data?.blogPosts.map(({id, Title, Body, Tags, CreatedAt}) => (
                        <tr key={id}>
                            <td>{id}</td>
                            <td>{Title}</td>
                            <td>{Body}</td>
                            <td>{Tags}</td>
                            <td>{CreatedAt}</td>
                        </tr>
                    ))}
                    </tbody> : <tbody><tr><td>No Blog Posts to show!</td></tr></tbody>}
            </table>
        </div>
)

export default ListBlogPosts

What did we do here? We created a simple table and we filled it with the data from Strapi. As you can notice we are using data?. with question mark, that is optional chaining because we don't want our code to throw exception if the data is somehow not ok. First we are checking whether blogPosts are there and whether we have blogPosts, we use .length here because we get an array of blogPosts so if there are blogPosts the .length won't be 0. If there are no blogPosts we show short info that there is no blog posts to show while if there are blogPosts we show them in the table through the map function.

Now we see a simple table with all the data we entered in the Strapi backend. In the next steps we will add editing and removing options to this table so we can handle it directly from the frontend client.

Thank you for reading!

21