A Complete Guide to Building and Deploying Your Own Website with React, Flask and Heroku
There’s something magical about putting your work out for other people to see. There’s a sense of deep pride infused with a sense that you can make anything happen — that it’s not too crazy to believe that you can build the next great service, product, idea, or company.
But it’s also easy to feel like you don’t have the knowledge or tools to make that happen . If someone just made the most basic of that sacred knowledge available, you would be off to the races! I felt that way when I first learned how to build web apps. For my first few weeks in the thorns of online resources and tutorials, I found a lot of great resources, but nothing consolidated. I couldn’t find anything that readily gave me space to take the tutorial product in my own direction. I stumbled through a lot of errors and endlessly consulted old StackOverflow threads.
This walkthrough will consolidate the dozens of hours I’ve spent searching for how to build a React-Flask app deployed on Heroku. By the end of the walkthrough, you should have something like this (don’t mind the domain name — it’s just a spare that I had lying around). Hopefully, you can use this tutorial to painlessly launch your next great idea!
Flask is a micro-framework for building web apps. Flask has a wide range of applications but today we’ll focus on using it to build the server side of our website. React is a tool for building dynamic user interfaces. It’ll unlock an enormous field of possibilities for developing our website. If you’re already familiar with HTML, it’s incredibly easy to pick up, and if not, there’s great documentation for specific use cases. We’ll use React to power the client side of our website. Our React client will make requests to our Flask server using Fetch API. So let’s start building!
Building the Flask Side
We’ll start with the Flask side. I created a folder to contain the code for the backend. I entered this folder and created a virtual environment in the folder with the terminal command
virtualenv env. This will store the python packages that will power the backend. You can find a list of the requirements in requirements.txt.
Flask is configured with a set of environment variables. This is generally kept in a file called .env. You can also use this file to inject other variables into your application. This is incredibly useful for storing API keys and keeping them secret. You do not want to upload your .env, environment folder, or some other cache files to Github. These files either contain sensitive information or are junk for other people trying to run your app. We can use .gitignore to prevent these files from going public.
Next, we’ll build out the structure of the application in a factory design pattern. You can read more about this design pattern here. We’ll use CORS to restrict who can make requests to our server. Flask-CORS is a great resource for accomplishing this task. CORS is really important for building secure web apps. It prevents malicious actors from making calls to your API. This is important for more reasons than we can cover in this walkthrough.
We’ll configure the settings for our app and CORS in utils/config.py. Furthermore, for our protected route, we’ll request a special session token, provided when the client requests to /get/unprotected. The protected route will be wrapped by a decorator called auth_required. This decorator looks for a session token in the incoming request header. It was inspired by a similar decorator provided by the Flask API documentation which is definitely worth checking out!
Otherwise, we can see the code for our simple app in routes/main.py.
We’re almost done with our Flask server! In the root folder, we’ll create a file called application.py which will produce our app from the factory created in __init__.py. We will also create a Procfile. Heroku will need these in order to host our server. Now for the client side.
Building the React Side
Building the frontend is made simple with the create-react-app package produced by the React team and Facebook. We can use this to quickly spin up a client side, then trim and add where necessary. I did this with
npx create-react-app demo-client where demo-client is the name of the folder.
After deleting some unnecessary files from the package, we’ll have a barebones React app. We’ll use some simple styling, contained in index.css, and we’ll install bootstrap with
yarn add bootstrapto make this a faster build. We’ll also need react-router-dom to handle our multiple pages and js-cookie to handle cookie settings.
Each of our pages will be represented as components, meeting in App.js. You’ll notice one component for our unprotected page, one for our protected page, one for posting data from the client, and a landing page. These components are built in the functional pattern, and for more information on what is happening in each component, refer to the React JS documentation.
For now, we are just interested in observing how data is sent between our client and server. This is especially important for the protected page, which requires credentials to be sent in the request header.
We’re almost done with our React side! Let’s create an .env file for our React app, so we can inject the address of the server when the app loads. React requires that environmental variables referenced in the app start with ‘REACT_APP_*’. To access this variable in the app we use ‘process.env.REACT_APP_*’ as seen above. Now let’s deploy!
Moving to Heroku
There are plenty of existing resources which cover how to deploy on Heroku. I’ll assume that you already have an account with Heroku, are configured, and know how to push to Heroku.
The key things to know for our project is that we’ll be deploying two Heroku applications: one for our React side and one for our Flask side. Once you’ve deployed these repositories, we’ll go into each of their settings and update their environment variables under the Config Vars tab. You will also need to give each of the Heroku apps their own custom domains for the cookies to work.
We’re almost done. For our React app, we’ll also need to use a special buildback called ‘https://buildpack-registry.s3.amazonaws.com/buildpacks/mars/create-react-app.tgz’. You can search for this under the Buildpacks tab in the settings for the React app in Heroku. This buildpack makes it easy to deploy instances of create-react-app on Heroku.
If you’ve done everything correctly, you should arrive at a web app like this! Because I don’t have SSL certificates for my client and server, the credential cookies won’t set and the protected page will reject you. I did this to save costs on this demo app :), but your project should have SSL set up for HTTPS!
If your client doesn’t seem to be communicating with your server, you most likely have a cookie problem. You can check to see if the cookie is being set in your browser by looking in the developer tools under ‘Application’, if you’re using Chrome. This React-Flask application structure requires both the client and server to be hosted on the same custom domain with different subdomains and SSL certificates. In your React app, the cookie should be set with samesite=none and secure=true. If you open your developer tools and you don’t see ‘sessionToken’ as one of your cookies, then you can be certain that your browser is rejecting the cookie that React is trying to set. Cookie permissions are difficult, but they are meant to prevent malicious actors from attacking your app.
Hopefully, you found this tutorial helpful and good luck with your next great project!