Support the ongoing development of Laravel.io →
Article Hero Image

Laravel Reverb and Vue 3 + TypeScript : Add Realtime to your App

5 Jun, 2024 5 min read

Photo by Félix Lam on Unsplash

In many modern web applications, WebSockets are used to implement realtime, live-updating user interfaces. When some data is updated on the server, a message is typically sent over a WebSocket connection to be handled by the client. WebSockets provide a more efficient alternative to continually polling your application's server for data changes that should be reflected in your UI.

Adding WebSockets and Vue + TypeScript to your Laravel 11 project you will build an amazing Robust Application. Now let's go through the installation process.

1. Installing Laravel 11

First of all you need to install laravel 11 project by typing : laravel new example-app . For more information about installation process go at laravel website

Once you finish installing Laravel 11 project; you may install Reverb using the install:broadcasting Artisan command behind the scenes, the install:broadcasting Artisan command will run the reverb:install command, which will install Reverb with a sensible set of default configuration options; for more detail checkout laravel documentation

2. Installing Vue 3

In order to set up vue 3 within your Laravel 11 Project you need to install this plugin @vitejs/plugin-vue by typing npm install --save-dev @vitejs/plugin-vue command :

You may then include the plugin in your vite.config.js configuration file. There are a few additional options you will need when using the Vue plugin with Laravel:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.ts'],
            refresh: true,
        }),
        vue(),
        
    ],
});

Make sure to change your app.js to ``app.ts because we are going to use TypeScript then type this command to install vue 3 npm install vue@latest

3. Adding Websockets to client App

Laravel Echo is a JavaScript library that makes it painless to subscribe to channels and listen for events broadcast by your server-side broadcasting driver. You may install Echo via the NPM package manager. In this example, we will also install the pusher-js package since Reverb utilizes the Pusher protocol for WebSocket subscriptions, channels, and messages:

npm install --save-dev laravel-echo pusher-js

Once Echo is installed, you are ready to create a fresh Echo instance in your application's JavaScript. you will see this in echo.js


import Echo from 'laravel-echo';

import Pusher from 'pusher-js';
window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

4.Installing TypeScript

First, install the TypeScript compiler into your project.

npm add -D typescript
# or
yarn add -D typescript

TypeScript configuration

The next step is to configure the compiler. TypeScript requires a configuration file tsconfig.json in the root directory of your project.

The presence of a tsconfig.json file in a directory indicates that the directory is the root of a TypeScript project. The tsconfig.json file specifies the root files and the compiler options required to compile the project.

First create a tsconfig.json at the root of your laravel 11 project and then copy paste these configuration into your tsconfig.json file :

{
  "compilerOptions": {
      "allowJs": true,
      "module": "ESNext",
      "lib": ["ES2020", "DOM", "DOM.Iterable"],
      "moduleResolution": "Node",
      "target": "esnext",
      "jsx": "preserve",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "noEmit": true,
      "isolatedModules": true,
      "types": ["vite/client"]
  },
  "exclude": ["node_modules", "public"],
  "include": [
      "resources/js/**/*.ts",
      "resources/js/**/*.d.ts",
      "resources/js/**/*.vue",
      "resources/js/app.ts",
  ],

}

After that, we need to install also vue-tsc wich is a wrapper around tsc checkout Vue documentation

npm i vue-tsc

Once you finish installing vue-tsc modify your package.json at the script section :

 "scripts": {
        "dev": "vite",
        "build": "vue-tsc --noEmit && vite build"
    },

5 Creating a Vue Instance in app.ts

First, get into ressources/js

app.ts

import './bootstrap';

import {createApp} from 'vue'
import App from './App.vue'

createApp(App)
.mount("#app")

Put this boiler plate in you App.vue file :

<script lang="ts" setup>
import {ref,onMounted} from "vue"

const count=ref<number>(0);

function setupEvent(){
        window.Echo.channel('testChannel')
        .listen('testingEvent', (e:any) => {
          console.log(e)
          // hello world in console 
        })
  }
  
onMounted(()=>{
  setupEvent()
})
</script>
<template>
  <div class="container">
  <h1>{{count}}</h1>
<button @click="count++">increment</button>
  <!-- <RouterView/> -->
  </div>
</template>

within ressources/js, create a folder types and then create in global.d.ts file and copy this in it. This code will add laravel Echo available to the Window Object interface.

interface Window {
    Echo:any;
}

Modify welcome.blade.php file

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>

    <body>
      <div id="app"></div>

          @vite([ 'resources/js/app.ts','resources/css/app.css'])
 <!-- the vite blade directive load script -->
    </body>
</html>

In order to broadcast an event from laravel we need first to create an event, type :

php artisan make:event testingEvent

in testingEvent.php file

class testingEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;
    public function __construct($message)
    {
        $this->message = $message;
    }
    public function broadcastWith(): array
    {
        return [
            'message' => $this->message,
        ];
    }
    public function broadcastOn(): array
    {
        return [
            new Channel('testChannel'),
        ];
    }
}

in web.php file import this event :

<?php
use App\Events\testingEvent;
use Illuminate\Support\Facades\Route;

Route::get('/', function() {
   testingEvent::dispatch("hello world");
    return view('welcome');
});

you are done; run these commands.

Laravel server

php artisan serve  

Reverb server

php artisan reverb:start

Queue server

php artisan queue:work

Vue server

npm run dev

get into the browser an run : http://127.0.0.1:8000/ then open an incognito window; you are going to get "hello world" in another open window in console.

You need a quick setup ? Then check out this Repository

Last updated 3 weeks ago.

bienfait-ijambo, driesvints liked this article

2
Like this article? Let the author know and give them a clap!
bienfait-ijambo (Bienfait-Ijambo) I'm versatile Fullstack dev with 6 years of experience. I'm ready to learn new things, to impact the society.

Other articles you might like

Article Hero Image November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
Article Hero Image November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
Article Hero Image November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.