More

    Build a Laravel Live Commenting System

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

      Try a free demo
    

    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.
    body a.novashare-ctt{display:block;background:#00abf0;margin:30px auto;padding:20px 20px 20px 15px;color:#fff;text-decoration:none!important;box-shadow:none!important;-webkit-box-shadow:none!important;-moz-box-shadow:none!important;border:none;border-left:5px solid #00abf0}body a.novashare-ctt:hover{color:#fff;border-left:5px solid #008cc4}body a.novashare-ctt:visited{color:#fff}body a.novashare-ctt *{pointer-events:none}body a.novashare-ctt .novashare-ctt-tweet{display:block;font-size:18px;line-height:27px;margin-bottom:10px}body a.novashare-ctt .novashare-ctt-cta-container{display:block;overflow:hidden}body a.novashare-ctt .novashare-ctt-cta{float:right}body a.novashare-ctt.novashare-ctt-cta-left .novashare-ctt-cta{float:left}body a.novashare-ctt .novashare-ctt-cta-text{font-size:16px;line-height:16px;vertical-align:middle}body a.novashare-ctt .novashare-ctt-cta-icon{margin-left:10px;display:inline-block;vertical-align:middle}body a.novashare-ctt .novashare-ctt-cta-icon svg{vertical-align:middle;height:18px}body a.novashare-ctt.novashare-ctt-simple{background:0 0;padding:10px 0 10px 20px;color:inherit}body a.novashare-ctt.novashare-ctt-simple-alt{background:#f9f9f9;padding:20px;color:#404040}body a.novashare-ctt.novashare-ctt-simple-alt:hover,body a.novashare-ctt.novashare-ctt-simple:hover{border-left:5px solid #008cc4}body a.novashare-ctt.novashare-ctt-simple .novashare-ctt-cta,body a.novashare-ctt.novashare-ctt-simple-alt .novashare-ctt-cta{color:#00abf0}body a.novashare-ctt.novashare-ctt-simple-alt:hover .novashare-ctt-cta,body a.novashare-ctt.novashare-ctt-simple:hover .novashare-ctt-cta{color:#008cc4}To build trust in your online community or blog, one crucial element you’ll want is a well-designed Laravel live commenting system. 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″>

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

    </head>
    <body>

    &lt;div id="app"&gt;
        &lt;div class="container"&gt;
            &lt;div class="question-wrapper"&gt;
                &lt;h5 class="is-size-2" style="color: #220052;"&gt;
                    What do you think about &lt;span style="color: #47b784;"&gt;Dogs&lt;/span&gt;?&lt;/h5&gt;
                &lt;br&gt;
                &lt;a href="#Form" class="button is-medium has-shadow has-text-white" style="background-color: #47b784"&gt;Comment&lt;/a&gt;
            &lt;/div&gt;
            &lt;br&gt;&lt;br&gt;
            &lt;comments&gt;&lt;/comments&gt;
            &lt;new-comment&gt;&lt;/new-comment&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;script async src="{{mix('js/app.js')}}"&gt;&lt;/script&gt;
    

    </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.

    Need a hosting solution that gives you a competitive edge? Kinsta’s got you covered with incredible speed, state-of-the-art security, and auto-scaling. Check out our plans

    Live 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>

    &lt;script&gt;
    

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

    },
    };
    </script>

    &lt;style lang="scss" scoped&gt;
    

    .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>

    &lt;script&gt;
    

    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>

    &lt;style scoped&gt;
    

    .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>

    &lt;script&gt;
    

    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>

    &lt;style scoped&gt;
    

    .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? 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!
     The post Build a Laravel Live Commenting System appeared first on Kinsta.

    Recent Articles

    Related Stories

    Stay on op - Ge the daily news in your inbox