Create a Recipe App with Gatsby and Strapi

Introduction

In this article, we’ll create a recipe application by utilizing Gatsby (a ReactJS based static site generator), Strapi (a NodeJS based headless CMS) and some dynamic GraphQL (via Apollo). By utilizing these technologies, we can quickly build an application that is flexible and open to further implementation. We’ll only build the basic components for now, but I’ll focus on the details that are important for building a static site from Strapi data and also show you how to dynamically query with Apollo. Some topics that will be covered:

  • Creating a Recipe content type, adding fields and setting permissions for CRUD operations in Strapi
  • Generating pages from Strapi by utilizing a Gatsby plugin to source the data automatically with very little configuration.
  • Configure Apollo to allow us to dynamically query specific recipes on our search page.
  • We’ll also create a custom resolver to accept variables that Apollo will utilize when searching for recipes.

This should be a fun little app! Hopefully you’ll have a bit of a better understanding on how to navigate around Strapi and see that it can be great for more than just building quick prototypes.

Setting up Strapi

For starters, you will want to make sure that you have NodeJS installed. It is recommended that you have at least Node v10 since it is currently labeled for LTS.

In this tutorial, I will be using MongoDB as my database, so I won’t really get into how to set this up for MySQL or PostgreSQL. However, you can setup an account for free. Now! Let’s get into the meat and potatoes of this recipe app…

Install Strapi globally by entering the following command:

 npm install strapi@beta -g

You can make sure that this is installed correctly by entering:

 strapi -v

If all is well, you’ll see something like 3.0.0-beta.x. Heyo! You’re now ready to move onto creating a new Strapi project.

Creating our Strapi Project

In your terminal, enter the following command:

strapi new recipe-api

Then, choose custom installation and Mongo as your default database client. You can press enter through the database name and then set your host to your connection string (found by clicking on Connect located in the cluster tab). It will contain something similar to xxxx.mongodb.net.

Now set +srv connection to TRUE and you can press enter through the port input. Set your username and password and set “Enable SSL connection” to YES.

NOTE: I ended up having to cd into my project direction and running npm install to get things to actually work properly. This may not be necessary for you.

Alright! Your new Strapi project should now be ready for configuration!

Adding a new Strapi Admin User

Now that you’ve setup the file structure for our backend, you should be able to setup your user for adding new content types. Create a new user:

Creating the Recipe Content Type

Configuring Permissions for Content Types

Setting roles and permissions

Generally, you’ll want to avoid giving non-authenticated users the ability to create, update or delete content. Since we’re not implementing authentication yet, we’ll give all users the ability to interact with the data.

Adding our First Recipe!

Congratulations! You created your first content type. Now you can navigate to http://localhost:1337/recipes and see a JSON of your recipe returned! If you don’t receive the expected response from that URL, check your api>recipe>config>routes.json file to determine what pathname you should be appending to your base url.

Setting up Gatsby

To get started you’ll want to make sure that you have the Gatsby CLI installed globally.

npm install -g gatsby-cli

Create a new Gatsby Site

Make sure that you are in your base project directory before you create your new Gatsby project. You don’t want to run the following inside of your Strapi directory.

gatsby new recipe-ui

You can now cd into that directory and test to make sure that the Gatsby project is running as expected:

cd recipe-ui && gatsby develop

That’s pretty much all you need to do to get a Gatsby project created and running. We’ll need to do some configuration and add some personal touch to craft this into a functional UI, but we’re well on our way now!

Configure Gatsby for Strapi

In order for us to source data from Strapi, we’ll need to utilize a Gatsby plugin and configure it properly.

 npm install --save gatsby-source-strapi

Add Strapi source plugin to Gatsby

Add Gatsby source plugin

Alright! Now we have Gatsby sourcing Strapi as we’d expect. Now you can run:

gatsby develop

And you should be able to visit localhost:8000/___graphql and see:

Modify Gatsby-node to build static recipe pages

Gatsby provides us with the ability to pull data and generate pages from it. You’ll need to add the logic to the gatsby-node.js file to source that data and map it to a template. Next, we’ll need to create the template file that Gatsby will use to format the data into our UI.

Create a template for page render

Create a new directory in your src directory called templates and add recipe.js to it. Now run:

gatsby develop

You should see something similar to the image below when you navigate to the slug that you created in Strapi. Congrats! Gatsby and Strapi are connected and you can add new recipes and see them appear on the site.

Heyo! Our recipes are being pulled in and rendered onto separate pages from Strapi with the power of Gatsby! Now, let’s configure our application to utilize Apollo client. This will allow us to dynamically create, read, update and delete recipes and will be a core component in our search functionality.

Adding Apollo Client

We’ll want to start by adding a few dependencies to our application. Make sure that you are in your UI directory and run the following:

npm install apollo-boost isomorphic-fetch react-apollo graphql-tag @apollo/react-hooks

Now that we have the dependencies installed, we’ll need to add the GraphQL plugin to Strapi that our client will use to perform CRUD operations. From your backend directory, run the following:

npm install strapi-plugin-graphql

You can also install this plugin directly from Strapi’s UI; however, the current version of beta that I’m using had some issues, so I found that just installing it manually was easier.

Enable the GraphQL plugin and notice that when you navigate to http://localhost:1337/graphql, you should see a GraphQL playground!

Configuring the Apollo Client

Now that we have an endpoint for Apollo to communicate with, we can configure the client from our UI. In your UI src directory, create a new directory named apollo and add the following files:

mkdir apollo && touch client.js wrap-root-element.js

Alright! Now we want to create our Apollo client in our client.js file:

This will enable us to hit the endpoint and create Queries and Mutations to pass through to GraphQL. However, in order for this to work, we need to wrap the root element with our ApolloProvider. In your wrap-root-element.js file, add the following:

Configure for Server Side Rendering

In your gatsby-browser.js and gatsby-ssr.js, add the following into those files so that server side rendering takes care of wrapping your application.

And that’s it for your Apollo configuration! Let’s move on to creating dynamic recipe search page so that we can utilize the power of Apollo for querying and mutating our data in Strapi!

Now that we have Apollo configured, let’s create a search page that will allow us to search for certain recipes based on their name. We’ll start with creating a simple search page that utilizes Apollo and then we’ll create a custom resolver in Strapi to handle our dynamic search. For starters, let’s create a recipe page. Navigate to the pages directory inside of src and create recipe-search.js

touch recipe-search.js

We’ll add some boilerplate code and utilize one of the built in resolvers to make sure that we’re receiving the data that we expect.

Awesome! Our query is working as expected!

Create a custom resolver in Strapi to return our desired results

This part of the build is a bit strange in the configuration since we’ll be adding a schema file that isn’t a normal GraphQL schema. We’ll end up doing the following:

  • Modify the main GraphQL schema in exports>graphql>schema.graphql
  • Create a new schema files in api>recipe>config
  • Modify our recipe controller to delegate our query request to a service worker
  • Modify our recipe services to handle the database query

Modify the Main GraphQL Schema

Add schema.graphql to Add the Custom Resolver

Modify Recipe.js in the Controllers Directory

Modify Recipe.js in the Services Directory

Modify Recipe Search

Lastly, we’ll want to modify our recipe-search.js to query our database with the search term from our input.

Let’s not forget about the supporting component for displaying the data:

IT’S ALIVE!!!!

Conclusion

I hope that you had some fun playing around with Strapi, GraphQL and React! Clearly, there is a bit of configuration at the start; however, once you have the project setup, the ability to expand on your ideas quickly makes it well worth the trouble! I’ll be modifying the code and trying to keep everything updated (and the styling will improve shortly as well). If you have any suggestions (i.e. features, optimizations, etc.), please reach out and I’ll be sure to get back to you.