Build a Comment Section for your NextJS blog using Redis and NextAuth
We will build a comment section for your blog in this tutorial️. The tech stack we will be:
- NextJS 13 (in App dir)
- NextAuth (for Authentication)
- Upstash Redis (for storing comments)
- SWR (for Caching and Revalidation of comments)
Let's start.
Handling Auth with NextAuth
Firstly, we can't just let anyone post a comment, right? Someone could just run a script to spam your blog with comments. Let's first build an Authentication system before letting people post a comment. We will use NextAuth.
Install next-auth
in your project.
This is the directory structure inside the App Directory
.
├── app
│ ├── api
│ │ └── auth
│ │ └── [...nextauth]
│ │ └── route.ts
│ ├── blog
│ │ ├── page.tsx
│ │ └── [...slug]
│ │ └── page.tsx
│ ├── components
│ │ └── LoginButton.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
Set up our Auth API route:
Create a new Github OAuth application from here to get the GITHUB_CLIENT_ID
and GITHUB_CLIENT_SECRET
.
Now, NextAuth allows you to Sign in and SignOut from any Client Component using signIn
and signOut
functions from next-auth
. But before that, you need to set up a Context Provider which wraps your entire application.
The SessionProvider
will allow you to access the session state from any Client component in the application.
You can access the session state using the useSession
hook from next-auth
. Here is a sample for a Login Button:
With this, our Auth system is in place. Now let's begin the server side routes to store comments in the Redis database.
Setting up Redis Database
- Head to Upstash and create a Redis Database.
- Choose a region close to your users and opt for TLS encryption.
- Install
@upstash/redis
package.
- Copy these tokens in your
.env.local
.
Lets write our API endpoints now in this directory structure:
.
├── app
│ ├── api
│ │ ├── auth
│ │ │ └── [...nextauth]
│ │ │ └── route.ts
│ │ ├── comment
│ │ │ ├── delete
│ │ │ │ └── route.ts
│ │ │ ├── get
│ │ │ │ └── route.ts
│ │ │ └── post
│ │ │ └── route.ts
│ │ └── lib
│ │ ├── getUser.ts
│ │ └── redis.ts
- Create a Redis Client Instance
That was it. Our Redis Client is now set up and all that is left is to set up the API routes for it in our application.
We will be using Redis Lists for storing the comments. They can act as a stack so the most recent comment is displayed at the top. Sure, we can also implement the sorting logic client side but when Redis already provides this data stucture, let's use it.
You can see the entire code here. Here is the gist of it:
-
Create a comment:
redis.lpush(referer, comment)
. This will push the comment in list having the keyreferer
-
Get all comments
redis.lrange(referer, 0, -1)
-
Delete a comment
redis.lrem(referer, 0, comment)
. This will delete all occurrences ofcomment
in the list with the keyreferer
.
Our API is now in place. Let's get to integrating the frontend with the backend.
Setting up the Client Side
It isn't that difficult. We just need to hit those endpoints we just created using fetch
.
We will be using a library called swr
for caching and revalidation of comments. But feel
free to use other libraries like React Query for it.
We make a useComment()
hook which will have onSubmit()
and onDelete()
handlers
for making requests.
Now our Comment section is done. We are able to fetch, post and delete comments. Next steps would be to create the components for Comment box and comments list. Here is a complete sample