How to Build a Real-time Chat App with Laravel, Vue.js, and Pusher
Time to read: 8 minutes
How to Build a Real-time Chat App with Laravel, Vue.js, and Pusher
Real-time chat applications like WhatsApp and Discord have witnessed a remarkable surge in popularity in recent years, revolutionising communication with instantaneous messaging. However, while building your own chat app with this functionality might seem daunting, it’s entirely achievable.
In this tutorial, you will learn how to build a real-time chat application using Laravel, Vue.js, and Pusher. You'll use the Laravel framework to build the back end of the chat application, a combination of Blade templates and Vue.js to develop the user interface and layout of the application, and the Pusher platform for the real-time chat functionality.
Prerequisites
To complete this tutorial, you will need the following:
- PHP 8.3 (or higher) installed
- Node and NPM installed
- Composer installed globally
- A Pusher account. Click here to create an account if you don't have one
- Basic knowledge of WebSockets
- Basic knowledge of the Vue.js framework would be nice, but is not essential
Backend setup
Begin by setting up all the necessary backend configurations required for the chat application.
Scaffold a new Laravel project
To get started with building your chat application, you need to create a new Laravel project using Composer and change into the project directory by running the below commands in your terminal.
Next, install Laravel Breeze using the command below.
Once the Laravel Breeze installation is complete, scaffold the authentication for the application. Do that by running the following commands one after the other.
When prompted, select the options below.
The final step in the scaffolding process is to add the necessary packages and config files for WebSocket and event broadcast. Run the command below in a new terminal instance or tab.
When prompted, select these options:
This command creates channels.php in the routes folder and broadcasting.php in the config folder. These files will hold the WebSocket configurations and install the necessary client libraries (Laravel Echo and pusher-js) needed to work with WebSockets.
With all of the scaffolding completed, start the application development server by running the commands below.
Once the application server is up, open http://localhost:8000/ in your browser. You should see the default Laravel welcome page with options to log in or register for your chat app, as shown in the image below.
The next step is to open the project in your preferred IDE or text editor.
Configure Pusher
Pusher is a cloud-hosted service that makes adding real-time functionality to applications easy. It acts as a real-time communication layer between servers and clients. This allows your backend server to instantly broadcast new data via Pusher to your Vue.js client.
Install the Pusher helper library by running the command below in a new terminal instance or tab.
Then, in your Pusher dashboard, create a new app by clicking Create App under Channels.
Next, fill out the form, as in the screenshot below, and click Create app.
After creating a new channels app, navigate to the App Keys section in the Pusher dashboard where you will find your Pusher credentials: App ID, Key, Secret, and Cluster. Note: these values as you will need them shortly.
Now, locate the .env file in the root directory of your project. This file is used to keep sensitive data and other configuration settings out of your code. Add the following lines to the bottom of the file:
Ensure you replace <your_pusher_app_id>
, <your_pusher_app_key>
, <your_pusher_app_secret>
, and <your_pusher_app_cluster>
with the actual values from your Pusher dashboard. Be careful to only replace the placeholder values with your actual credentials and do not alter the keys. This setup will enable your application to connect to Pusher's cloud servers and set Pusher as your broadcast driver.
Setup model and migration
After scaffolding the application, the next step is to create a model and a corresponding database migration. This will allow us to store chat messages and user information in the database. Run the following command in your terminal to create a model with a corresponding migration file.
This command will generate ChatMessages.php in the app/Models directory and a migration file in the database/Migrations directory.
Open app/Models and update the content of ChatMessages.php with this.
In the code above, the $fillable
property allows sender_id
, receiver_id
, and text
to be mass-assigned. Additionally, the model defines two many-to-one relationships: the sender relationship links to the user model via the sender_id
, and the receiver relationship links to the user model via receiver_id
, representing the sender and receiver of the message, respectively.
Next, navigate to database/Migrations and update the file that ends with create_chat_messages_table.php with the following code.
In the migration above, the database schema of the chat application is defined. This schema includes an id
for each message, foreign keys sender_id
and receiver_id
that reference the users
table, a text
column to store the content of the message, and timestamp
columns to record when each message is created and updated.
After updating the model and migration, the next step is to run the migration. Do that by running the command below in your terminal.
Setup the event broadcast
Next, set up the event broadcast by navigating to channels.php file in the routes folder and update it with the following.
In the code above, a new broadcast channel named "chat" is defined, and a closure is passed to ensure that only authenticated users can subscribe to the channel.
After defining the channel, create a new event which will be broadcast to the client on the "chat" channel. Run the command below in your terminal to generate the event class.
The command will create a new file called MessageSent.php in the app/Events directory. Open the MessageSent.php file and update it with the below content.
In the code above, the user and the message are passed into the constructor. The broadcastOn()
method specifies that the event will be broadcast on a private channel named "chat", while the broadcastWith()
method adds the chat message to the broadcast payload.
Create the controller
The next step is to create a controller class that will contain all the application logic. To create the controller, run the command below in your terminal.
This command will create a new file called ChatController.php in the app/Http/Controllers folder.
Open the ChatController.php file and replace the content with the following.
In the code above, the necessary imports required for the chat application are added. In the index()
function, messages exchanged between the currently authenticated user and the specified user are retrieved while eager-loading the sender and receiver information using the relationships. In the store()
function, a new message from the currently authenticated user to the specified user is saved to the database, and the MessageSent
event is broadcasted on the chat channel.
Update the routes
Now, it's time to update the routing table. So, in the web.php file located in the routes folder, add the following imports at the beginning of the file.
Next, replace the dashboard route with the following .
These routes set up the necessary endpoints for the chat application. The /dashboard
route displays a list of users, excluding the current user. The /chat/{user}
route loads the chat interface for a selected user. The Route::resource
line sets up routes for retrieving and sending messages using the ChatController
.
Frontend setup
Now that the backend part of the chat application is fully set up, it’s time to build the user interface of the chat application.
Install Vue.js
First, install Vue.js and the necessary plugin to detect .vue files by running the following commands:
Create a new Vue.js component
Next, navigate to resources/js and create a new folder called components. In the newly created components folder, create a new file called ChatBox.vue. Update its content with the following.
The code above is a Vue.js component responsible for the chat functionality. The <template>
section defines the HTML structure, including a div for displaying messages and an input area for sending new messages, with each message conditionally styled to distinguish between messages sent by the current user and others.
In the <script>
section, the receiver and sender are passed as props
to identify the two users currently chatting. Within the setup
function, reactive references messages
, newMessage
, and messagesBox
are defined. The scrollToBottom()
function ensures that the chat view always scrolls to display the latest message, while the sendMessage()
function handles sending new messages to the server and updating the chat view accordingly.
The formatTimestamp()
function formats the message timestamps for display. The onMounted
lifecycle hook fetches existing messages and listens for the MessageSent
event on the “chat”channel using Laravel Echo. Finally, the <style>
section adds CSS styles to define the layout, the appearance of the messages, and the input area.
Update the Echo.js and App.js file
After creating the chat components, the next step is to update the JavaScript files. In the resources/js directory, locate the echo.js file and replace the content of the file with the following.
In the updated echo.js file, Echo is configured to use Pusher as the broadcaster for real-time events. It uses the key and cluster information specified earlier in our .env file to connect the application to the Pusher service.
Then, replace the content of the resources/js/app.js file with the content below
In the updated app.js file, the Vue.js application is set up by importing necessary dependencies and creating a new instance. The ChatBox
component is registered to the alias chat-box
, and mounted to the HTML element with the id app
, enabling the chat functionality in your application.
Update the vite.config.js file
Vite is a build tool that is responsible for building and bundling your frontend assets. You’ll need to update its config file so it can detect and build Vue.js components.
To do that, in the root directory, open the vite.config.js and update it with the following content:
In the updated vite.config.js, the laravel-vite-plugin
is configured to handle the CSS and JS files for your Laravel application. The @vitejs/plugin-vue
plugin is also included to enable support for Vue.js single-file components. Additionally, the resolve
section sets up an alias to use the Vue ES module build, which is necessary for single-file component support. This configuration ensures that Vite can properly process and serve your application during the development and build stages.
Update the Blade templates
The final step in the frontend setup is updating the Blade templates. Navigate to resources/views and update dashboard.blade.php with the below content.
In the updated dashboard.blade.php, the list of users profiled on the system is returned, such that a logged-in user can chat with any of them.
Also in resources/views, create a new file chat.blade.php and update it with the following content.
This file holds the Vue.js component responsible for the chat functionality. It sets up the layout and includes the chat-box
component, passing the authenticated user as the sender and the selected user as the receiver as props to it.
Test the chat application
It’s finally time to see your chat app in action. By default Laravel events are dispatched on queues, therefore you’ll need to start up a queue worker instance so your event can be processed. Run the command below in your terminal to start your queue.
Next, register two new users. Log in with one user in a regular browser tab, and log in with the other user in an incognito tab. Then, select each other on both tabs to start chatting.
Below is a video demonstration of the chat application.
That’s how to build a real-time chat application using Laravel, Pusher and, Vue.js
This tutorial has equipped you with the knowledge to effectively build a real-time chat application. You learned how to set up the backend logic and event broadcast using WebSockets with Laravel, handle real-time communication with Pusher, and build a dynamic frontend using Vue.js to listen for and display events.
With these skills, you can now create more complex real-time applications, or add additional features to your chat app. The possibilities are endless!
Keep building!
Oluwadamilola Oshungboye is a Software Engineer and Technical Writer who loves writing about Cloud and Backend Technologies. He can be reached on X (formerly known as Twitter).
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.