Building a Realtime Chat App with Laravel 5.4 and VueJS

With the announcement of Laravel Dusk, a browser automation and testing API tool, I noticed a cool chunk of demo code. It represents a realtime app that features user interacting using WebSockets:

This inspired me to build an app for which I could use that same exact snippet of code. It ended up involving quite a few steps, but Laravel made it easy!

See the code for this tutorial on Github

Note: I’ve since updated the master branch of the code on Github which fixed some breaking changes to how Laravel Mix is compiled. They are not updated in the individual steps below.

Step 1: Setup

In this video, I get the dev version of Laravel installed, get the new Laravel Mix up and running, and render and example Vue component.

Step 2: Vue Components

Now I can start developing several Vue Components to create an interactive chat application. None of the data is persisted to the server yet, but it looks real!

Step 3: Laravel Backend

Now I am POSTing chat messages to the server and start loading messages from the server. It’s basic Laravel models and routes in this video.

Step 4: Laravel Echo

I have a functional chat app connected to the server, but I have to refresh to see new messages from other people. This step involves setting up Event Broadcasting within Laravel and implementing Laravel Echo on the front end using Pusher.

Step 5: Laravel Dusk

I’m finally to the point where I’m ready to test my realtime chat application. I install Laravel Dusk, write a couple example tests, and talk about the benefits of this sort of testing environment.

That’s all that I have! Let me know if you have had similar experiences with Laravel and what sort of things you’ve done with Laravel Dusk.

  • poldixD

    Thank you very much for the tutorial!

  • Winarto Saputro

    Awesome tuts. Thank you very much

  • José Alejandro Realza

    Wow! A great tutorial for learn the new features from Laravel 5.4 and others plus

  • Dino Lukavackic

    Do more Laravel 5.4 stuff… You obviously have the knack for this.

    • jplhomer

      Thanks, Dino 😀

  • questjone

    Hi there! Very nice and easy to follow tutorial. I’m watching video #3 now and would like to make you a question. How can I use the Laravel Auth with my own Login screen created in VueJS?

    • jplhomer

      Hi! You’d probably want to mimic however the scaffolded login form works. At the end of the day, it’s just a HTTP POST request, so you should be able to use whatever form you’d like.

  • Awesome! Thank u very much! keep it up! and success! 😉

  • jimmy8646

    Very good tutorial!!

  • Nick Harris

    AWESOME tutorial! Laracasts should offer to pay you good money for this to host on their site as a series. Seriously, you managed to teach me in an hour what I struggled and failed to learn in two days from Laracasts and Laravel docs.

    • jplhomer

      Thanks Nick – very flattering! I’m a big fan of Laracasts, but I’m glad you found this tutorial beneficial.

  • mikah

    It’s not working.. for now stuck in laravel echo where object broadcast not shown on console.log(e)…..

    • jplhomer

      Not sure what your error is. Be sure to use the correct Pusher cluster if you’re not located in the US.

      • mikah

        I already put cluster in US. I finally made it to show the object by replacing broadcast_driver in env from log to pusher, but the echo not working (already enable in app.config)

      • Rolf Guescini

        Hi, and thanks for a nice tutorial! I am having the same issues as mikah it seems. I am broadcasting data, and since the Event uses PresenceChannel(‘chatroom’), I had to update the chatroom – name to: ‘presence-chatroom’ as it seems Laravel is concatietaing The Channel type and the name:

        local.INFO: Broadcasting [AppEventsMessagePosted] on channels [presence-chatroom] with payload:

        I am still not receiving data live after step 4,and I am totally stuck.

        Pusher is configured with:

        options’ => [
        ‘cluster’ => ‘eu’,
        ‘encrypted’ => true,


        import Echo from ‘laravel-echo’
        window.Pusher = require(‘pusher-js’);
        window.Echo = new Echo({
        broadcaster: ‘pusher’,
        key: ‘KEY’,
        cluster: ‘eu’,
        encrypted: true

        Also tried both:

        .listen(‘MessagePosted’, function (e) {
        console.log(“SOMETHING HAPPENED”)
        message: e.message.message

        console.log(“EVENT: “+JSON.stringify(e));


        .listen(‘.App.Events.MessagePosted’, function (e) {
        console.log(“SOMETHING HAPPENED”)
        message: e.message.message

        console.log(“EVENT: “+JSON.stringify(e));

        Any ideas ?

  • Miguel Arias

    Man this is awesome. Good thing people like you exist! lol


    Hi, i get following error: POST http://localhost/broadcasting/auth
    404 (Not Found) .The error is full correct for me, i want to change the
    path/url, but i can’t find anywhere in the Broadcasting documentation
    where i can change the path or it’s written in the documentation and i
    don’t get it.. Has anybody an idea where i can change the standard
    broadcasting path or how to change it by a extra route? Thank you very
    much for any help. 🙂

  • Nelson Izah

    Awesome tut, really helpful

  • Michael Tilford

    Great tutorial, but I’m stuck around the 11:30 mark on lesson 4.

    When I load the page, I get this console error:
    Pusher : Error : {“type”:”WebSocketError”,”error”:{“type”:”PusherError”,”data”:{“code”:null,”message”:”Auth value for subscription to presence-chatroom is invalid: should be of format ‘key:signature'”}}}

    I’m on Laravel 5.4, fresh install, so it’s not the .env problem where PUSHER_KEY was changed to PUSHER_APP_KEY. Also changed BROADCAST_DRIVER=pusher. I’m on the default US server.

    Any idea what could be going on?

  • Nguyễn Thanh Phong

    please give me file .env . email: [email protected]

  • Nguyễn Thanh Phong

    11:40 Part 4 :
    problem console.log(e) not returns object

  • Kaspar Martin Suursalu

    You could add as annotation or something to enable pusher as broadcaster in env. took 20 min to figure out why not pushing .. other wise great tut. Keep it up.

    • danish

      can you configure this on my machine i am new to laravel

  • kvein rey

    How can i implement with user to user conversation? i know this a public conversation right.

    • jplhomer

      Correct – I’d start by adding a column to the Message model, or a join table, to allow User to hasMany() Messages. You can also adjust the channel permissions.

  • Really great post. Spent hours trying to work out what was wrong with my online list and chat app. Found this and followed the parts I needed and it worked straight away.

    Had followed an older tutorial and it had things like `this.users.pop(user);` for the leaving. I’m not great at front-end but I’m learning and pop didn’t sound right. Thanks for the filter line 🙂

  • I followed the code in the video and check with the github copy to make
    sure my code was correct and it is. Yet every time I click refresh the
    entire chat messages disappear. anybody had a similar issue or can
    recommend a solution?

  • Jordan Plamondon

    I’m facing these errors.
    Do you know how to fix this?…

    ERROR Failed to compile with 5 errors 22:10:52

    This dependency was not found:

    * /Users/jordanplamondon/code/laravel-realtime-chat-demo/resources/assets/sass/app.scss in multi ./resources/assets/js/app.js ./resources/assets/sass/app.scss

    To install it, you can run: npm install –save /Users/jordanplamondon/code/laravel-realtime-chat-demo/resources/assets/sass/app.scss

    These relative modules were not found:

    * ./components/Example.vue in ./resources/assets/js/app.js
    * ./components/ChatMessage.vue in ./resources/assets/js/app.js
    * ./components/ChatLog.vue in ./resources/assets/js/app.js
    * ./components/ChatComposer.vue in ./resources/assets/js/app.js

    • jplhomer

      Not sure – would you try updating Laravel Mix to the latest version and see if that helps?

      • Jordan Plamondon

        yeah it helps! Thank you so much

    • Prince Lionel N’zi

      Also facing a similar issue when I run “npm run dev”

      λ npm run dev

      > @ dev C:wamp64wwwlaravel-realtime-chat-demo
      > node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js –progress –hide-modules –config=node_modules/laravel-mix/setup/webpack.config.js

      throw err;

      Error: Cannot find module ‘C:wamp64wwwlaravel-realtime-chat-demonode_modulescross-envbincross-env.js’
      at Function.Module._resolveFilename (module.js:469:15)
      at Function.Module._load (module.js:417:25)
      at Module.runMain (module.js:604:10)
      at run (bootstrap_node.js:394:7)
      at startup (bootstrap_node.js:149:9)
      at bootstrap_node.js:509:3
      npm ERR! code ELIFECYCLE
      npm ERR! errno 1
      npm ERR! @ dev: `node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js –progress –hide-modules –config=node_modules/laravel-mix/setup/webpack.config.js`
      npm ERR! Exit status 1
      npm ERR!
      npm ERR! Failed at the @ dev script.
      npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

      npm ERR! A complete log of this run can be found in:
      npm ERR! C:UsersPrince Lionel N’ziAppDataRoamingnpm-cache_logs2017-06-19T19_40_48_319Z-debug.log

  • Genius

    Hello. Why my: laravel new chatdemo –dev wont work ? Im using Windows 10.
    I have also installed – npm install, on cmp, and it goes ERROR.
    I cant figure out what is wrong ? Any help?

    • jplhomer

      What errors are you seeing in the command line? Do you have NodeJS installed on your machine?

  • BigB

    Hey there. I was following your tutorial and right now I’m on video #2. I know you made this video a while back, in your videos I don’t see much warnings are shown, but once I do it I see errors. There is one I’m following in video #2 I cant seem to fix the warnings from.

    [Vue warn]: Error in render function: “TypeError: Cannot read property ‘message’ of undefined” found in
    —> at C:wamp64wwwvue-chatresourcesassetsjscomponentsChatMessage.vue

    I get that warning after around the 10 minutes. Do you know how the fix that undefined?

    • jplhomer

      Not sure what the issue is, but you could try the following:

      – Make sure you have ENV[‘BROADCASTER’] set to ‘pusher’
      – Make sure you have your Pusher keys set up
      – Make sure you have a Pusher cluster option set if you’re not located in the US

      • BigB

        Nope had nothing to do with that. After some time I found out where it came from….
        I didn’t delete in chat.blade.php
        Certainly overlooked that part in the video. >.<

  • Sugam Malviya

    Hello Josh, I’m getting user object null while fetching the messages 10:39 (Part 3). I’m using Mysql. Please help!

    • Sugam Malviya

      Solved.. thanks Once again
      Just need to define foreign_key here!
      public function user() {
      return $this->belongsTo(‘AppUser’, ‘user_id’);

  • BigB

    On video 4. When @{{ usersInRoom.length }} is added to chat.blade.php, and the other code are in place, it doesnt show a number but “usersInRoom.length”. What is happening? I have usersInRoom in the app.js and the here,leaving…. also

    • BigB

      Scratch this… my stupid mistake… ignore this

  • BigB

    Woohoo finally finished it, despite some places with trouble!

  • Hayk Baghdasaryan

    You are missing Vendor folder in your repo.

  • Erez T

    @video3 8:15 *axios*

    I’m not getting any response back as if axios isn’t loaded.
    I tried also:
    window.axios = require(‘axios’);
    window.axios.defaults.headers.common = {
    ‘X-CSRF-TOKEN’: window.Laravel.csrfToken,
    ‘X-Requested-With’: ‘XMLHttpRequest’

    together also with;
    import axios from “axios”;

    also, no success.
    I’m not getting any response back, no errors also, unfortunately.

  • Johenel Progilla Labayan

    Hi after running npm run watch I cant run it with myproject.test/ in my browser, any Idea ?

  • Akeem

    Nice tutorial but im stuck on video 2 with this error,
    [Vue warn]: Error in render function: “TypeError: Cannot read property ‘message’ of undefined”.
    Help will be seriously appreciated. thanks

    • Gorjanco Mitrevski

      Hey, did you solve this? I have the same problem, but with the name of the user.

      • Gorjanco Mitrevski

        I solved this. The problem was that in the Event MessagePosted the $user object was not defined as public.
        Adding public $user; under the public $message; line in the event will solve the problem.

  • Carlos Frutos

    What would be a good approach for custom channels, for 1-1 conversations or group conversations, concerning the channels, broadcasts and vue components parts

    • jplhomer

      I’d approach it by adding a column to your messages table corresponding for “recipient_id”! And authorize it accordingly for your broadcasts. Vue components should be able to be reused for the most part.


        You could give us an example as it would be from one to one please!

  • Adroit~Adio

    Just can’t believe that what have been battling with in months, is now a done deal with this tutorial. Great job man

    • jplhomer

      Thank you!

  • Salisu

    Wow, so elegant and self explanatory. I’m an angular developer but this tutorial made me want to add Vue to my front end stack. Angular would have required more lines of code for this.

    • jplhomer

      Thanks, Salisu – glad you enjoyed it!

  • jerauf

    I followed the tutorial religiously but am getting a 500 error on posting to /messages (with an “uncaught promise”). Also, Pusher is giving me websocket errors.

    What do I do?

  • J Man

    Does it work with Laravel 5.5 ?

  • J Man

    Never realize how powerful Laravel actually is. I m going to try this for laravel 5.5

  • ghulamali2612

    hi. can you please how can i create custom middleware for private channel. I tried
    Broadcast::route([‘middleware’ => [‘web’, ‘auth:custom’]]) but it check both guard. I want to check 1 at a time not both. any suggestion

  • César David Cedeño

    Awesome tutorial! Thanks a lot!