This article was originally published on this site

To build trust in your online community or blog, one crucial element you’ll want is a well-designed Laravel live commenting system.

However, it’s not easy to get it right on the first try unless you rely on self-hosted commenting systems such as Disqus or Commento, each of which comes with its own set of disadvantages. They own your data, offer limited designs and customizations, and most importantly, they aren’t free.
With these limitations, if the idea of building your real-time commenting system — with the benefits of controlling your data, designing and customizing the look and feel to fit into your blog — appeals to you, keep reading.
This article will teach you how to develop a well-designed and real-time commenting system with different commenting functionalities. Following the principles of building a real-time chat application with Vue.js and Socket.io, we’ll use Laravel, Pusher, and React to develop the real-time commenting system.
Let’s dive in!

What We’ll Build
We’ll build a real-time commenting system that can be integrated into any website or blog to build trust in the community.
To build trust in your online community or blog, one crucial element you’ll want is a well-designed Laravel live commenting system. 💬 Learn how to get started here ⤵Click to Tweet
Building Blocks Overview: Laravel, Pusher, and Vue
Before we dive into the development, let’s discuss the technologies we’ll use to develop our real-time commenting system.
Laravel
Laravel is an open-source MVC-oriented PHP framework. It’s used to build simple to complex PHP web applications known for their elegant syntax. Learning what Laravel is essential to building this commenting system.
Pusher
Pusher enables developers to create real-time features at scale. This article will combine Laravel Echo to create a real-time broadcast event to the Pusher server and display the content on the frontend with Vue.js.
Vue.js
Vue.js is our frontend framework of choice. Vue.js is a progressive JavaScript frontend framework known for its easy-to-learn and straightforward approach to frontend development. We’ll be using Vue.js to develop our real-time commenting system.
Building the Commenting System
If the commenting system we’ve outlined above sounds like what you want, let’s move on to building it out.
1. Install and Setup Laravel, Pusher, and Echo
The installation and setting up of Laravel, Echo, and Pusher is straightforward as Laravel has done all the background tasks by setting up and configuring Laravel Echo to work with Pusher perfectly.
Firstly, we’ll start by installing and configuring Laravel, our backend PHP framework. You can grab a new instance of Laravel with this command, provided you’ve installed the Laravel CLI globally:
laravel new commenter
Your new Laravel instance will be installed in a folder called commenter. Let’s open the folder in our VSCode and navigate to it in our terminal:
cd commenter

code .
Before we start our development server, let’s install and configure some necessary packages that will be used for the project.
Run this command to install the Pusher PHP SDK:
composer require pusher/pusher-php-server
Run this command to install the necessary NPM packages for the Vue.js frontend:
npm install –save laravel-echo pusher-js
Next, we’ll configure the Laravel Echo and Pusher. Open your resources/js/bootstrap.js file and paste in the following scripts:
window._ = require(“lodash”);
window.axios = require(“axios”);
window.moment = require(“moment”);
window.axios.defaults.headers.common[“X-Requested-With”] = “XMLHttpRequest”;
window.axios.defaults.headers.post[“Content-Type”] =
“application/x-www-form-urlencoded”;
window.axios.defaults.headers.common.crossDomain = true;
window.axios.defaults.baseURL = “/api”;
let token = document.head.querySelector(‘meta[name=”csrf-token”]’);
if (token) {
window.axios.defaults.headers.common[“X-CSRF-TOKEN”] = token.content;
} else {
console.error(“CSRF token not found”);
}

/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that Laravel broadcasts. Echo and event broadcasting
* allows your team to build robust real-time web applications quickly.
*/
import Echo from “laravel-echo”;
window.Pusher = require(“pusher-js”);
window.Echo = new Echo({
broadcaster: “pusher”,
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true
});
You’ll notice from the script above that we’re just configuring Axios instance with our default configurations. Next, we’ll configure Laravel Echo to use Pusher and its configurations.
2. Database Setup and Migration
Next, we’re going to create and set up our database to store the comments for persistence. We’ll be using SQLite, though you can use any database client of your choice.
Create a database.sqlite file inside the database folder and update your .env file as follows:
DB_CONNECTION=sqlite
DB_DATABASE=/Users/all/paths/to/project/commenter_be/database/database.sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=
Next, run this command to create the Comment migration and update it with the following scripts:
php artisan make:migration create_comments_table
Open the database/migrations/xxxx_create_comments_table_xxxx.php file and paste in this code:
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
class CreateCommentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(‘comments’, function (Blueprint $table) {
$table->id();
$table->string(‘content’);
$table->string(‘author’);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists(‘comments’);
}
}
This will create a new comments database table and add content and author columns.
Finally, to create the migration, run this command:
php artisan migrate
3. Creating Models
In Laravel, models are significant — they’re the surest way to communicate with our database and handle data management.
To create a model in Laravel, we’ll run the following command:
php artisan make:model Comment
Next, open the app/models/Comment.php file and paste in the following code:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Comment extends Model
{
use HasFactory;
protected $fillable = [‘content’, ‘author’];
}

The $fillable array allows us to create and update the model in mass.
4. Creating Controllers
Controllers are crucial because they house all the logic, business, and otherwise, of our applications, so let’s create one to handle the commenting logic:

Sign Up For the Newsletter

Want to know how we increased our traffic over 1000%?
Join 20,000+ others who get our weekly newsletter with insider WordPress tips!


Subscribe Now

php artisan make:controller CommentController
Next, open the app/Http/Controllers/CommentController.php file and paste in the following code:
<?php
namespace AppHttpControllers;
use AppModelsComment;
use AppEventsCommentEvent;
use IlluminateHttpRequest;

class CommentController extends Controller
{
//
public function index()
{
return view(‘comments’);
}
public function fetchComments()
{
$comments = Comment::all();
return response()->json($comments);
}
public function store(Request $request)
{
$comment = Comment::create($request->all());
event(new CommentEvent($comment));
return $comment;
}
}
The controller has three different methods: return a comment view, fetch all the comments, and store a new comment, respectively. Most importantly, we fire up an event each time we store a new comment, which the frontend will listen for to update the relevant page with the new comment in real-time using Pusher and Laravel Echo.
5. Creating Routes
To configure our routes properly, we’ll need to update lots of files, so let’s get started.
Firstly, we’re going to update the api.php file in the routes folder. Open the file and add the following code:
use AppHttpControllersCommentController;
//…

Route::get(‘/’, [CommentController::class, ‘index’]);
Route::get(‘/comments’, [CommentController::class, ‘fetchComments’]);
Route::post(‘/comments’, [CommentController::class, ‘store’]);
Next, open the channels.php file in the same folder and add the following code to authorize the event we fired earlier:
Broadcast::channel(‘comment’, function ($user) {
return true;
});
Next, open the web.php file in the same folder and add the following code to redirect our request to the homepage, where Vue.js will pick it up:
use AppHttpControllersCommentController;
//…

Route::get(‘/’, [CommentController::class, ‘index’]);
Lastly, we’ll create a new blade file in the resources/views folder called comments.blade.php and add the following code:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″ />
<title>Commenter</title>
<meta name=”csrf-token” content=”{{ csrf_token() }}”>
<meta name=”viewport” content=”width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0″>

<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css” />
<style>
.container {
margin: 0 auto;
position: relative;
width: unset;
}
#app {
width: 60%;
margin: 4rem auto;
}
.question-wrapper {
text-align: center;
}
</style>
</head>
<body>

<div id=”app”>
<div class=”container”>
<div class=”question-wrapper”>
<h5 class=”is-size-2″ style=”color: #220052;”>
What do you think about <span style=”color: #47b784;”>Dogs</span>?</h5>
<br>
<a href=”#Form” class=”button is-medium has-shadow has-text-white” style=”background-color: #47b784″>Comment</a>
</div>
<br><br>
<comments></comments>
<new-comment></new-comment>
</div>
</div>
<script async src=”{{mix(‘js/app.js’)}}”></script>
</body>
</html>
The script adds a post title and a Vue component to display and add new comments to the post title created above.
Run the following commands to test if you get everything correctly:
npm run watch

php artisan serve
If you’re presented with this page, you’re ready to move to the next step in this article.

Live commenting system in LaravelLive commenting system in Laravel

6. Setting Up Vue (Frontend)
We’ll create and set up our Vue instance to create and display all the comments made on this post.
We’ll start with setting up our Vuex store. Create the following files in the resource/js/store folder.
Create Comment State
Create actions.js and add the following code:
let actions = {
ADD_COMMENT({ commit }, comment) {
return new Promise((resolve, reject) => {
axios
.post(`/comments`, comment)
.then(response => {
resolve(response);
})
.catch(err => {
reject(err);
});
});
},
GET_COMMENTS({ commit }) {
axios
.get(“/comments”)
.then(res => {
{
commit(“GET_COMMENTS”, res.data);
}
})
.catch(err => {
console.log(err);
});
}
};
export default actions;
The Action file makes a call to the comment endpoint in the backend.
Next, create a getters.js file and add the following code:
let getters = {
comments: state => {
return state.comments;
}
};
export default getters;
The Getter file is used to retrieve all the comments in the state.
Create the mutations.js file and paste it into the following code:
let mutations = {
GET_COMMENTS(state, comments) {
state.comments = comments;
},
ADD_COMMENT(state, comment) {
state.comments = […state.comments, comment];
}
};
export default mutations;
Next, create a state.js file and paste it into the following code:
let state = {
comments: [] };
export default state;
Lastly, we’ll add everything to the index.js file exported to the Vue instance, create an index.js file and add the following:
import Vue from “vue”;
import Vuex from “vuex”;
import actions from “./actions”;
import mutations from “./mutations”;
import getters from “./getters”;
import state from “./state”;
Vue.use(Vuex);
export default new Vuex.Store({
state,
mutations,
getters,
actions
});
Create Components
Lastly, we’re going to create our comment components to display and add new comments. Let’s start by creating the single comment component.
Create a folder in the resource/js folder called components, add the comment.vue and add the following code:
<template>
<li class=”comment-wrapper animate slideInLeft”>
<div class=”profile”>
</div>
<div class=”msg has-shadow”>
<div class=”msg-body”>
<p class=”name”>
{{ comment.author }} <span class=”date”>{{ posted_at }}</span>
</p>
<p class=”content”>{{ comment.content }}</p>
</div>
</div>
</li>
</template>

<script>
export default {
name: “Comment”,
props: [“comment”],
computed: {
posted_at() {
return moment(this.comment.created_at).format(“MMMM Do YYYY”);
},

},
};
</script>

<style lang=”scss” scoped>
.comment-wrapper {
list-style: none;
text-align: left;
overflow: hidden;
margin-bottom: 2em;
padding: 0.4em;
.profile {
width: 80px;
float: left;
}
.msg-body {
padding: 0.8em;
color: #666;
line-height: 1.5;
}
.msg {
width: 86%;
float: left;
background-color: #fff;
border-radius: 0 5px 5px 5px;
position: relative;
&::after {
content: ” “;
position: absolute;
left: -13px;
top: 0;
border: 14px solid transparent;
border-top-color: #fff;
}
}
.date {
float: right;
}
.name {
margin: 0;
color: #999;
font-weight: 700;
font-size: 0.8em;
}
p:last-child {
margin-top: 0.6em;
margin-bottom: 0;
}
}
</style>
Next, create the following file called comments.vue in the same folder and add the following code:
<template>
<div class=”container”>
<ul class=”comment-list”>
<Comment
:key=”comment.id”
v-for=”comment in comments”
:comment=”comment”
></Comment>
</ul>
</div>
</template>

<script>
import { mapGetters } from “vuex”;
import Comment from “./Comment”;
export default {
name: “Comments”,
components: { Comment },
mounted() {
this.$store.dispatch(“GET_COMMENTS”);
this.listen();
},
methods: {
listen() {
Echo.channel(“comment”).listen(“comment”, (e) => {
console.log(e);
this.$store.commit(“ADD_COMMENT”, e);
});
},
},
computed: {
…mapGetters([“comments”]),
},
};
</script>

<style scoped>
.comment-list {
padding: 1em 0;
margin-bottom: 15px;
}
</style>
Lastly, create a file called NewComment.vue and add the following code:
<template>
<div id=”commentForm” class=”box has-shadow has-background-white”>
<form @keyup.enter=”postComment”>
<div class=”field has-margin-top”>
<div class=”field has-margin-top”>
<label class=”label”>Your name</label>
<div class=”control”>
<input
type=”text”
placeholder=”Your name”
class=”input is-medium”
v-model=”comment.author”
/>
</div>
</div>
<div class=”field has-margin-top”>
<label class=”label”>Your comment</label>
<div class=”control”>
<textarea
style=”height: 100px”
name=”comment”
class=”input is-medium”
autocomplete=”true”
v-model=”comment.content”
placeholder=”lorem ipsum”
></textarea>
</div>
</div>
<div class=”control has-margin-top”>
<button
style=”background-color: #47b784″
:class=”{ ‘is-loading’: submit }”
class=”button has-shadow is-medium has-text-white”
:disabled=”!isValid”
@click.prevent=”postComment”
type=”submit”
>
Submit
</button>
</div>
</div>
</form>
<br />
</div>
</template>

<script>
export default {
name: “NewComment”,
data() {
return {
submit: false,
comment: {
content: “”,
author: “”,
},
};
},
methods: {
postComment() {
this.submit = true;
this.$store
.dispatch(“ADD_COMMENT”, this.comment)
.then((response) => {
this.submit = false;
if (response.data) console.log(“success”);
})
.catch((err) => {
console.log(err);
this.submit = false;
});
},
},
computed: {
isValid() {
return this.comment.content !== “” && this.comment.author !== “”;
},
},
};
</script>

<style scoped>
.has-margin-top {
margin-top: 15px;
}
</style>
Now, open the app.js file and add the following code to register the Vue components you created earlier:
// resource/js/app.js

require(“./bootstrap”);
window.Vue = require(“vue”);
import store from “./store/index”;

Vue.component(“comment”, require(“./components/Comment”));
Vue.component(“comments”, require(“./components/Comments”));
Vue.component(“new-comment”, require(“./components/NewComment”));

const app = new Vue({
el: “#app”,
store
});
Want to build your own personalized commenting system? 💬 This post has everything you need to get started 🚀Click to Tweet
Summary
And that’s it! You’ve just learned how to build a live commenting system for your site using Laravel.
We’ve discussed the benefits of creating and managing a commenting system in your quest to build trust in your community or blog. We’ve also explored how to develop a well-designed and real-time commenting system from the ground up, utilizing different commenting functionalities.
You can clone the source code of this project in this Github repo.
What do you think of the Laravel live commenting system we’ve built together? Let us know in the comments!
 

Save time, costs and maximize site performance with:

  • Instant help from WordPress hosting experts, 24/7.
  • Cloudflare Enterprise integration.
  • Global audience reach with 28 data centers worldwide.
  • Optimization with our built-in Application Performance Monitoring.

All of that and much more, in one plan with no long-term contracts, assisted migrations, and a 30-day-money-back-guarantee. Check out our plans or talk to sales to find the plan that’s right for you.