Tyler Reicks
Posted on December 9, 2020
Intro
For this blog post, I am going to go over how I built my blog site with Strapi and React. I'm going to keep this as short and simple as possible. I followed along with the tutorial from Strapi themselves but there were hiccups along the way that I will address. Also, the tutorial only goes over how to make the blog locally. In this post, I'll explain what I did to deploy it out to the worldwide web.
Here is the link to the Strapi blog post that I followed along with. Overall it was great. It clearly described every step of the process and explained why things were done the way they were.
Initial hurdles
The first small issue I noticed was in their instructions. One of the first commands you have to run is yarn strapi install graphql
. Before this command is run in the terminal you must ensure you are in the correct directory. Make sure to cd backend
in your terminal. You make this backend folder in the step before this, they just don't tell you to navigate to the newly created folder before the next step. If you don't do this you will install graphql in the root folder of the project and your backend for the blog will not work.
Another problem I ran into was how to organize the project for version control. I use VSCode's built-in source control almost 100% of the time for my projects. The way this tutorial gets setup (I'm starting to learn many projects are set up this way), you'll end up with two separate directories for your frontend and backend code. Since the backend was largely already set up for me by Strapi I only committed my frontend code to GitHub. My backend directory also has version control but it is managed through the Heroku CLI. I'm sure there is a better way to manage this, but at the time I was too lazy to look into other options. Especially, when my current setup was working perfectly fine.
Lastly, I ran into an issue that I couldn't quite understand while running the frontend locally. Here was the error:
- Could not find "client" in the context or passed in as an option. Wrap the root component in an , or pass an ApolloClient instance in via options
Luckily a couple of users had already solved this problem and put it in the comments. Link to comment here.
Everything else in the tutorial was pretty self-explanatory though! If I did have any confusion on something Strapi was so kind to add a video to the tutorial which also guided people through the process of creating the blog. I was able to have the blog finished and running locally on my machine pretty quickly. The next step was deploying the blog out to Heroku and Netlify.
Deploying to Heroku and Netlify
If you haven't used this stack with other projects before, from what I've gathered, Heroku is used to host your backend server and Netlify is used to host the frontend (at least that is what the tutorial recommended).
Heroku
Strapi has great documentation on how to deploy their backend to Heroku. Here is the link to that. Quick note, I created a Heroku project for this blog while I was still going through the tutorial. Pro tip: don't do that. The Strapi documentation shows you how to create the Heroku project in your backend folder which is so much easier. But if you took the same route I did, make sure to skip those create Heroku project steps (step 6) in the Strapi Heroku docs and connect to your existing project.
I used PostgreSQL for this. They also give you an option to use MongoDB. I'm sure both are great, but seemed like the PostgreSQL route was simpler.
Other than that the Heroku backend set up was pretty straight forward. Let's get to deploying the frontend.
Netlify
I think the Netlify set up might have been the easiest part of the project. Like I mentioned above, I had already pushed up my frontend directory to GitHub. All I had to do was make a Netlify account and connect my GitHub repo to my Netlify server (they step you through this process when you make a Netlify account).
Just like that my frontend code was being hosted on Netlify, but there was one problem. My Heroku backend wasn't connected to my Netlify frontend. That issue can easily be solved in your .env
file in your frontend directory. Originally, your backend is set to your localhost URL. I think by default in the Strapi tutorial it is https://localhost:1337
. You'll need to change that to the link of your Heroku app you just created. Pro tip: Make sure there is no trailing slash in the URL. For example, your .env
file should have this one line in it: REACT_APP_BACKEND_URL="https://*your-app-name*.herokuapp.com"
.
There we go! Now you should have your blog uploaded to the internet for the whole world to see. Next, I'll go over what I'll call an "optional issue".
Image upload with Cloudinary
Figuring out how to upload an image for a blog post was a real pain. What is the issue you may ask? Here is the answer straight from the Strapi docs:
- Heroku's file system doesn't support local uploading of files as they will be wiped when Heroku "Cycles" the dyno. This type of file system is called ephemeral, which means the file system only lasts until the dyno is restarted (with Heroku this happens any time you redeploy or during their regular restart which can happen every few hours or every day). Due to Heroku's file system, you will need to use an upload provider such as AWS S3, Cloudinary, or Rackspace.
One very easy way to get around this is to simply not add any pictures to your blog posts (this is why I consider this an optional issue). If you do go this route, make sure an image is not a required field in the Strapi admin portal (it was by default when I created my Articles content type).
I decided to use Cloudinary, but in hindsight, I think AWS would have been easier. I'm not giving Cloudinary enough credit though. It really wasn't that hard. I was just being stupid.
First, you want to head over to the Strapi Provider for Cloudinary npm package page. This page will show you how to add the Cloudinary provider to your Strapi blog.
Second, I set up my configuration differently than they recommended. Before I get into what I did, I should disclose that this is probably not a best practice. Instead of using an .env
file for the Cloudinary config variables I just put them in the plugins.js
file statically as strings. Yes, I know. For some reason when I was trying to use environment variables Cloudinary wasn't getting hooked up correctly. Here is a code example of what I did in my backend/config/plugins.js
file:
module.exports = ({ env }) => ({
// ...
upload: {
provider: "cloudinary",
providerOptions: {
cloud_name: "add_cloudinary_name_here",
api_key: "add_api_key_here",
api_secret: "add_api_secret_here",
},
},
// ...
});
Definitely not the best way to solve that problem but it indeed worked.
Conclusion
Overall this was a really fun project. If you're new to coding, this tutorial (along with the video) walks you through the process very well. There may be a couple of hiccups to figure out, but hopefully, this article solves most of them. Like always, peace ✌️ and happy coding!
Posted on December 9, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.