Build a Customer Support Live Chat App With Laravel and React Hooks

Customer support live chat is an incredible tool for collecting valuable feedback from your customers and increasing your website engagement rate. With that said, it can take weeks or even months to build a functional, scalable, reliable real-time chat application. Luckily, Stream Chat makes it super easy to create such an app quickly; you can build a reliable chat app in just hours with Stream's Chat API!

In this tutorial, we are going to build a customer support Live Chat app using Laravel, Stream Chat and ReactJS.

The full source code to this tutorial can be found on GitHub.


To follow along with this tutorial, please ensure you have the following installed on your machine:

A basic understanding of Laravel, ReactJS, and JavaScript will also be helpful.

Setting Up Laravel and Stream

Run the command below to create a new Laravel application:

Setting Up Laravel Front-End Scaffolding for React

To begin setting up your front-end scaffolding, install a general laravel/ui package with Composer:

To specify that you'll be using React to build your application, choose the React UI Package using the command below:

Once you are finished installing the required packages to make Laravel and React work together, you can proceed to set up your Stream Chat application with Laravel!

Setting Up Stream Chat with Laravel

First, you'll need to create an account on the Stream website. Head over to Stream to create a free account, by clicking on the SIGNUP button at the top right corner of the home page:

Once you create an account, you’ll be logged in and sent to your dashboard. In your dashboard, you'll find your API KEY, API SECRET and PRODUCTION APP ID, as shown below:

Add these credentials from your Stream dashboard to your environment variables file (.env), like this:

The prefix MIX_ enables the React front end to access the environment variables.

Now that we've connected in our keys, let’s install the Stream Chat PHP client so that we can interact with the Stream API from Laravel. Run the command below to install the Stream client with composer:

Then, run yarn in your terminal to install node dependencies bootstrapped by Laravel.

We are now finished setting up Stream Chat with Laravel! Let’s move on to install Stream Chat on the front end, and to install React Router, as we’ll need it to navigate to different pages of the app.

Run the command below to install both of these packages:

We are now finished with the app set up! Let’s get into some coding!

To prepare ourselves to start coding, let’s compile our static files, start our development server, and watch it for changes. Run the command below to do that:

Next, open a new terminal window/tab and run the PHP artisan command to serve the app:

At this point, your Laravel application will be running on port 8000!

Building the Application Backend

Let’s start by creating API routes. In the backend, we’ll create two functionalities: The first is to generate a token, while the second is to create a channel.

To start with, create two endpoints by adding the following code to the ./routes/api.php file:

Let’s create the controller for this route!


Run the command below to create a new controller called ChatMessagesController:

Generating Your Token and Channel

Open ./app/Http/Controllers/ repository, then, copy the code below to the ChatMessagesController.php file:

The above file consists of two functions and a constructor function. The constructor is used to instantiate Stream Chat. The function generateToken generates a token, while the function getChannel creates a new channel and returns the channel.

The Front End — The React Path

In the front end, we’ll create the admin chat functionality and the customer interface. We’ll send a message, listen to that message, and update the UI with the latest message.

This is where most of the work will be done. With that said, you can choose to move some of the jobs to the backend, if you like.

Let’s start with Routing!

Create a Wildcard Route

Replace the content of the ./route/web.php file with the code below:

The code above creates a wildcard route for our application. With this, our app will only return a view in - ./resources/views/app.blade.php. Next, create the app.blade file in the ./resources/views directory. Move the code below into app.blade file; this HTML excerpt is the first entry point template of the React app, where we’ll add chat bubbles:

Let’s proceed to create the App component!

Create the App Component

The App Component will be the base component of our React Components. So, we are renaming the Example.js file, located at ./resources/js/components/ (which is generated by Laravel) to App.js, then replace the code in that file with the code below:

Then, to accommodate for this file name change, open ./resources/assets/js/app.js and replace


In the App.js file, we are importing a client Chat component and an AdminChat component.

The reason for having two components is to distinguish between our chat screens (Client/Admin); we'll use React Router to route to the correct component, as needed. With that said, at this point, our application will throw an error if we try to access either, as we have not yet created either of these components. Let's dive into creating the Chat component!

Creating the Chat Component for the Client

First, we'll create the component for the client/user. Create a file called Chat.js in the directory ./resources/js/components/Chat/, and then copy the code below into that file:

To style this newly created component, we'll also create a file called Chat.css in the directory ./resources/js/components/Chat/, which will be populated with the following code:

Now, if you hit the URL "", you'll be able to view the page for user chat! The page should look like the picture below:

Creating the Chat Component for Admin

Next, we'll create the component for the admin! Create a file called AdminChat.js in the directory ./resources/js/components/Admin/ and copy in the code below, which renders the JSX for the Admin chat screen:

Just like for the client component, we'll go ahead and create a CSS style for AdminChat component. Create a file called AdminChat.css in the directory ./resources/js/components/Admin/ and add the code below:

Now, if you hit the URL "", you can view the page for admin chat! The page should look like the picture below:

Chat Logic

Let's jump into the actual chatting logic for the client-side!

Add the code below to the Chat.js file located at ./resources/js/components/Chat/:

Then, to take care of the admin side, add the code below to the AdminChat.js file located at ./resources/js/components/Admin/:

Now, let’s review the methods we used.

useState() - We use hooks to manage State in our application. Here we used useState and useRef to maintain the state of the client, channel, message and messageData:

useEffect() - We use the React useEffect hook to run the functions initializeClient and createChannel. Because the initializationClient method will make a network call and get the data that our app requires to properly render the component, it makes sense that we execute it in the useEffect hook:

initializeClient() - This method calls the API endpoint to generate a token for the client. It then initializes StreamChat, sets the user and verifies the token before updating the state with the client object:

createChannel() - This method calls our endpoint to create a channel and then passes to required data to the channel instance, and, finally, watches the channel for any new messages. If there is a new message, it will update the state with the new message data.

The most interesting part about creating a live chat application with Stream is that you don’t need to build one-one chat any differently than you would a group chat; you just need to set the members of the channel to two (2) users and the channel title to an empty string, and, boom, you have a one to one chat:

We’ll hardcode the names of the members (admin and client) for the sake of this tutorial.

getMessageHandler() - This method gets the message entered from the textbox and then updates our state with it:

SendMessageHander - Finally, we'll send the message to Stream, if the message is not an empty string:

We'll then listen to the message:

And push the new message to the UI.

Rendering the Chats Dynamically

When the event listener gets the message, we push the code to the UI using the bubble template. Add the following code to the Chat.js file located at ./resources/js/components/Chat/. This should be added immediately after the
tag inside the

tag with class name panel-body msg_container_base:

You should do the same to the Admin side (./resources/js/components/Admin/AdminChat.js file):

The difference between the admin and the client is that, in the admin part, we send "admin" as the logged-in user, while we set the "client" as the logged-in user on the client-side.

Congratulations 👍, your app should be up and running!

Hit the URL http://localhost:8000 to start chatting as a client and then visit the Admin URL (http://localhost:8000/admin) to respond to the client’s messages.

Wrapping Up

Cheers, I can’t wait to see the amazing applications you’ll build with Stream. Check out Stream Chat and the associated docs to learn more about Stream and the API/SDK!

Thanks for reading and happy coding!