Building A To-Do List with Blitz.js & Redis
Blitz.js is a React framework that was originally forked from Next.js. Today we’ll build a Blitz.js To-Do application that stores tasks in Upstash. Without further ado, let’s get started!
Setup
You’ll need to install Blitz.js on your computer to get started.
NPM:
Yarn:
To create a new Blitz.js app, use blitz new
and cd into the directory.
blitz new blitzjs-todo && cd blitzjs-todo
Great, now let’s install TailwindCSS to style our website.
blitz install tailwind
Lastly, let's install the Upstash JS SDK to make calls to the Upstash API easier.
NPM:
npm i @upstash/redis
Yarn:
yarn i @upstash/redis
At this point, you should run blitz dev
to make sure everything is working correctly. Try making an account and signing in too. It should look like this if you’ve done everything correctly so far.
In addition, your file structure should look like this:
Copy these UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN
from the Upstash Console into the file called .env
for now. It should look like this:
# This env file should be checked into source control
# This is the place for default values for all environments
# Values in `.env.local` and `.env.production` will override these values
UPSTASH_REDIS_REST_URL=YOUR_URL_HERE
UPSTASH_REDIS_REST_TOKEN=YOUR_TOKEN_HERE
We’ve set up our Blitz.js application completely now! Let’s start implementing our To-Do list.
Implementation
Blitz.js comes with User Authentication built in! Let’s leverage this to make private to-do lists for each user.
First, let's initialize the Upstash JS SDK in /lib/redis.ts
We’ll need to make 3 different API Routes to access our To-Do lists.
Navigate to app/api
and make a file called getall.ts
. Once you’ve done so, paste the following code in:
Let’s go over how this API Route works, step by step. First, we make a request to the route. On the route itself, we validate that the user is logged in. If there is no user, we return a “Not Authorized” response. If there is a user, then we fetch our Upstash Redis database to find all To-Dos that are currently in the list. This will fetch about a hundred To-Dos.
Q: Wait, how are we supposed to add To-Dos in the first place? A: Good question! Let’s do that next!
Once again, paste the following code into a new file called add.ts
in app/api
.
This API route is quite similar to the last one, but notice that we’ve added more checks in the fifth line. That’s because this request is not a GET
request, rather, it is a POST
request. Notice how we check for three things. First, we make sure that the request is actually a POST
request. Next, we make sure that there is JSON or text in req.body.data
. Finally, we make sure the user is logged in. If all of these little checks are passed, we can push our To-Do to our Redis list on Upstash. If there is any sort of error while fetching, we can return a 500 by using .catch
.
The last route we need to add is one to remove our To-Dos. Once you finish something, you have to cross it out of course! Let’s add our last API Route in app/api/remove.ts
. Copy the following code in to the file:
Notice anything similar? That’s because this route is almost identical to the add
API Route. The major difference here, is that we are using LREM
, not LPUSH
, to remove an item from Redis.
Building The Frontend
To start off, let’s delete everything in app/pages/index.js
and write our To-Do list step by step.
At the top of the file, paste these imports in.
We will be using React Hooks to build the core functionality of our To-Do list. Let’s implement some of the core features of the list.
The <Main/>
component is the core of our application. A closer look at its code tells us how we use it. At the top of our component, we initialize state for our application. We also declare a ref
for later use in our “New To-Do” input. You may also notice the usage of antiCSRFToken
! Blitz.js requires the use of these tokens when fetching any API Routes to prevent any sort of malicious actor from harming your site. It’s nice to have, in my opinion!
We use three main functions to handle our data on the website. These three are:
handleAddTodo
handleRemoveTodo
fetchTodos
We call fetchTodos
as soon as the page loads, to load all To-Dos that the user still needs to complete. When a user removes or adds a To-Do, we call fetchTodos
again to reflect that change on the website!
If a user is not logged in, the user will be prompted to login to the website before seeing this page.
You can sign up or log in if you do not already have a session on the website. Remember, you cannot store your To-Dos without an account, and all API Routes require you to be authenticated with an AntiCSRFToken
!
But wait, one more important step! We have to export the page!
As you can see above, Blitz.js uses an approach slightly different from Next, but the approach is the same at its core for now. We use the Suspense
that we imported earlier to show a user that the app is loading, and then we show our </Main>
component after it finishes loading!
To see your changes in effect, run this in your console one more time, and navigate to your app in the browser.
If you followed the directions, your application should look something along the lines of this once you login and add a few To-Dos:
You can remove a To-Do by clicking over the box next to it, that’s what the removeTodo
function is for 😉.
Congratulations!
I hope you learned something new by reading this blog post, and if you didn’t, remember it doesn’t hurt to brush up your skills! Blitz.js is pivoting focus away from Next.js, so it may be a completely different framework in the future, but stay tuned on their website here!
Project Source: GitHub Link
Working Demo: Demo Link
Have feedback? Make sure to follow @upstash on Twitter, and join the Discord server!