Building a Serverless Realtime Chat application with Pusher and NextJS
Let’s build a chat application with Pusher’s API
Why Pusher?
Pusher provides a number of affordable, easy to use APIs to add Realtime functionality to Web applications. From Realtime communication that allows users send instant messages to each other to Realtime location that allows users know the exact location of their packages anywhere in the world, Pusher makes it easy for businesses to focus on their core competencies while leveraging the power of Pusher to scale their application.
Here’s a sneak peak of what we’ll be building.
You could quite easily get a Full chat application setup in under an hour.
You can see a live demo here.
Prerequisites
- Local installation of Node.js
- Local installation of Yarn
- Basic knowledge of React and React hooks
- Basic knowledge of Node.js
Brief overview of Pusher’s APIs
Pusher has two major products Channels and Beams to help you take your application to the next level. Channels allows for realtime communication between devices while Beams sends notifications and updates to your users devices.
This article will focus on using the Channels API to quickly build a realtime chat application.
Setting up Pusher
First off, we will build the backend of our chat application using NodeJS and azure functions.
To get started, you’ll need to sign up for an account on Pusher. We’ll be working with the Channels API. Select the Channels Sandbox to get started.
Next, let’s give our app a name. For this example, we will call our app pusher-chat-location-demo.
Select React for the Front end tech stack and Node.js for the backend (this step is optional).
Setting up our server
We’ll be building this demo using NextJS, a React framework that allows us write serverless Node.js functions within our application.
Run the command below to generate a new Next.js application with CORS preconfigured.
yarn create next-app --example api-routes-cors pusher-chat-demo
Next, we will need to setup Pusher on our server.
Navigate into pages/api and create a new folder called pusher and a file called index.js. This creates an api route for us at /api/pusher
Now, we can run the command to install the Pusher library.
yarn add pusher
With Pusher installed, we can now setup our app keys using environment variables. In Next.js, we can setup environment variables by creating an .env.local file in the root of our directory and storing all our environment variables there. We can then access those variables in our app using process.env.VARIABLE_NAME.
Navigate to the App Keys section of your Pusher dashboard to copy your app keys.
Paste these variables into the .env.local file you created above.
Finally, in your pages/api/pusher/index.js file, create a new instance of pusher and initialize with your keys. Your code should look something like below.
Setting up the Frontend
With our server setup, the next step is to setup the Client side of our application.
On the client side, we’ll need to subscribe to events from our server. To do that, we’ll need to install a client side package for the pusher API. We’ll also use axios to make requests to our server. Run the command below to install pusher-js.
yarn add pusher-js axios
Next, we’ll need to create an additional variable in our .env.local file to define our key
for use on the client side. By convention, Next.js requires environment variables used on the client side to have the prefix NEXT_PUBLIC
. In your env.local, define
NEXT_PUBLIC_KEY= "YOUR_PUBLIC_KEY"
With that done, we can begin writing the code for the frontend of our application.
_app.js
First, we will allow users to login to the chat application using only their name. Once logged in, we’ll keep track of their name.We’ll store the state for the name inside our _app.js
file. We’ll also handle the login action here before redirecting the user to the chat page itself.
From the code above, we’re passing passing an handleLoginChange function which will keep track of the name a user inputs and storing that in the sender state.
We’re also handling the login event and passing the function down to components.
pages/index.js
Our index.js is a simple file. This is where we’ll display the login input to the user allowing them to login with their name.
NB: To keep this example clean and simple, I’ve removed the tailwind classes used for styling. See the Github repo for the complete example code.
You can replace the <Button /> component with a simply button tag with a type of submit.
Chat.js
Once a user enters their name and hit enter, we redirect them to our /chat route.
In your pages directory, create a new file called chat.js. The main logic of our application will happen within this file.
First, we’ll call the useEffect hook. When the Chat page mounts, we’ll create a new Pusher instance and initialize it with our appkey
. Next, we’ll subscribe to the chat channel, which is the same channel messages from users in our app are being sent to on the server.
Finally, we’ll bind to the chat channel we’ve created to get all the messages being sent. We’ll store that in a state to be eventually displayed to the user.
Finally, when our application unmounts from the DOM, we’ll unsubscribe the user from the chat channel.
Notice that in our handleSubmit function, we’re making POST requests to our server each time the user sends a message. We can pass any number of objects we want in the body of the POST request.
Here’s the full code on GitHub.
Bonus
In the next part of this article, we will build on this example. We’ll use the Channels API to show which users are online and the City and Country they’re joining the chat from in Realtime.