This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

📣 Try the fastest hosting platform with pay-as-you-go pricing & 24/7 expert support! MIGRATE NOW →

Create a Comments System with Laravel And Vuejs

Updated on September 23, 2021

12 Min Read
comment and reply system in laravel

In my previous article on Laravel and Vue.js, I created a realtime chatroom using Laravel, Vuej.s and Pusher.

In this piece, I will use Laravel and the Vue.js Javascript framework to create a Laravel comment system. This system is not as real time as the chatroom, but you will be able to see the new comments and replies for a post/page instantly.

VueJS enables Laravel to build the front-end so the application doesn’t have to reload pages whenever an update is made. VueJS helps form a full-scale event-driven web application that oversees all the activities on the frontend.

For the Laravel comment system I will create a separate comment component in view that can be added to any web page and blog post. Registered members of the system could perform the following  actions:

  • Add new comments
  • Reply to comments
  • Up and Down votes
  • Mark spam comments

This system will be based on the following technologies:

  • Bootstrap
  • Loadash
  • Vue-resource
  • Laravel Mix

The complete code for this comment system can be found in the github repo. Hear here for a live demo of the application.

Create Migration Tables for Comments

First, I need to create tables in which I am going to save the comments, mark comments spam and save the records for voting.

Start with the following command to create a new migration file:

php artisan make:migration comments

Now open the newly created file and paste the following code inside the `Up()` method:

Schema::create('comments', function (Blueprint $table) {

           $table->increments('id');

           $table->text('comment');

           $table->integer('votes')->default(0);

           $table->integer('spam')->default(0);

           $table->integer('reply_id')->default(0);

           $table->string('page_id')->default(0);

           $table->integer('users_id');

           $table->timestamps();

       });



       Schema::create('comment_user_vote', function (Blueprint $table) {

           $table->integer('comment_id');

           $table->integer('user_id');

           $table->string('vote',11);

       });



       Schema::create('comment_spam', function (Blueprint $table) {

           $table->integer('comment_id');

           $table->integer('user_id');

       });

The schema for the tables are simple. First I created the comments table in which I am going to save the comments. In the second table (comment_user_vote), I am going to save the users who have voted on the comments. In the last table, comment_spam, I will save the comment id of the comments that the users have marked as spam.

Now, run the following command to migrate all the tables:

php artisan migrate

Create Auth for Comment System

I will create the Laravel built-in auth so that only the registered user can add comments.

Start with the following command:

php artisan make:auth

You might also like: Set up Easy Vue Pagination for Laravel

Create Models for the Comment System

Let’s first create the model for the comments table.

Start with the following command to create the model:

php artisan make:model Comment

Open the newly created file (located in the app folder). Replace the existing code with the following code:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model

{

   //

   /**

    * Fillable fields for a course

    *

    * @return array

    */

   protected $fillable = ['comment','votes','spam','reply_id','page_id','users_id'];

   protected $dates = ['created_at', 'updated_at'];

   public function replies()

   {

       return $this->hasMany('App\Comment','id','reply_id');

   }

}

In the above code I defined the `$fillable` columns, `$dates` columns of the table and created `replies()` method which has the one-many relationship with its own table.

Now create a model for comment_user_vote. Run the following command:

php artisan make:model CommentVote

Now open the new created file and replace the existing code with the following:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class CommentVote extends Model

{

   //

   protected $fillable = ['comment_id','user_id','vote'];

   protected $table = "comment_user_vote";

   public $timestamps = false;

}

Next, create the model for the last table comment_spam through the following command:

php artisan make:model CommentSpam

Open the file and replace the existing code with the following code:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class CommentSpam extends Model

{

   //

   protected $fillable = ['comment_id','user_id'];

   protected $table = "comment_spam";

   public $timestamps = false;

}

Stop Wasting Time on Servers

Cloudways handle server management for you so you can focus on creating great apps and keeping your clients happy.

Create the Controller for Comment

To create a controller for comment, run the following command:

php artisan make:controller CommentController

Open the newly created file and start creating methods in it.

Save a new Comment

Start by adding a method which will save a new comment or reply:

/**

    * Store a newly created resource in storage.

    *

    * @param  \Illuminate\Http\Request  $request

    * @return \Illuminate\Http\Response

    */

   public function store(Request $request)

   {

       $this->validate($request, [

       'comment' => 'required',

       'reply_id' => 'filled',

       'page_id' => 'filled',

       'users_id' => 'required',

       ]);

       $comment = Comment::create($request->all());

       if($comment)

           return [ "status" => "true","commentId" => $comment->id ];

   }

The above code is pretty simple as I am getting the inputs. The code also makes sure that they exists and then save it all.

Voting And Marking Comments as Spam

Let’s now create a new function through which I can handle the upvoting and downvoting of comments.This will also handle the marking of comments as spam.

   /**

    * Update the specified resource in storage.

    *

    * @param  \Illuminate\Http\Request  $request

    * @param  $commentId

    * @param  $type

    * @return \Illuminate\Http\Response

    */

   public function update(Request $request, $commentId,$type)

   {

       if($type == "vote"){          

           $this->validate($request, [

           'vote' => 'required',

           'users_id' => 'required',

           ]);



           $comments = Comment::find($commentId);

           $data = [

               "comment_id" => $commentId,

               'vote' => $request->vote,

               'user_id' => $request->users_id,

           ];


           if($request->vote == "up"){

               $comment = $comments->first();

               $vote = $comment->votes;

               $vote++;

               $comments->votes = $vote;

               $comments->save();

           }


           if($request->vote == "down"){

               $comment = $comments->first();

               $vote = $comment->votes;

               $vote--;

               $comments->votes = $vote;

               $comments->save();

           }


           if(CommentVote::create($data))

               return "true";

       }

       if($type == "spam"){
          
           $this->validate($request, [

               'users_id' => 'required',

           ]);

           $comments = Comment::find($commentId);

           $comment = $comments->first();

           $spam = $comment->spam;

           $spam++;

           $comments->spam = $spam;

           $comments->save();

           $data = [

               "comment_id" => $commentId,

               'user_id' => $request->users_id,

           ];



           if(CommentSpam::create($data))

               return "true";

       }

   }

The above function has three parameters. The first parameter is the request which is incoming, the second one is the comment Id, and the third is the type. Through the `$type` variable, I will check the user action (vote the comment or mark it spam). Next, according to the type, the request is validated. If the type is vote, I first get the comment and then check the user intention ( i.e up or downvote the comment). Then I perform the operation and save the comment.  Marking a comment as spam follows a similar process.

You Might Also Like: Vue Validation in Laravel to Handle Form Requests

Get the Comments

Next, I will create a function that will get all the comments and the replies.

/**

    * Get Comments for pageId

    *

    * @return Comments

    */

   public function index($pageId)

   {

       //

       $comments = Comment::where('page_id',$pageId)->get();

       $commentsData = []

       foreach ($comments as $key) {

           $user = User::find($key->users_id);

           $name = $user->name;

           $replies = $this->replies($key->id);

           $photo = $user->first()->photo_url;

           // dd($photo->photo_url);

           $reply = 0;

           $vote = 0;

           $voteStatus = 0;

           $spam = 0;

           if(Auth::user()){

               $voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

               $spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();              

               if($voteByUser){

                   $vote = 1;

                   $voteStatus = $voteByUser->vote;

               }

               if($spamComment){

                   $spam = 1;

               }

           }          

           if(sizeof($replies) > 0){

               $reply = 1;

           }

           if(!$spam){

               array_push($commentsData,[

                   "name" => $name,

                   "photo_url" => (string)$photo,

                   "commentid" => $key->id,

                   "comment" => $key->comment,

                   "votes" => $key->votes,

                   "reply" => $reply,

                   "votedByUser" =>$vote,

                   "vote" =>$voteStatus,

                   "spam" => $spam,

                   "replies" => $replies,

                   "date" => $key->created_at->toDateTimeString()

               ]);

           }       

       }

       $collection = collect($commentsData);

       return $collection->sortBy('votes');

   }

   protected function replies($commentId)

   {

       $comments = Comment::where('reply_id',$commentId)->get();

       $replies = [];

       foreach ($comments as $key) {

           $user = User::find($key->users_id);

           $name = $user->name;

           $photo = $user->first()->photo_url;

           $vote = 0;

           $voteStatus = 0;

           $spam = 0;        

           if(Auth::user()){

               $voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

               $spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

               if($voteByUser){

                   $vote = 1;

                   $voteStatus = $voteByUser->vote;

               }

               if($spamComment){

                   $spam = 1;

               }

           }

           if(!$spam){        

               array_push($replies,[

                   "name" => $name,

                   "photo_url" => $photo,

                   "commentid" => $key->id,

                   "comment" => $key->comment,

                   "votes" => $key->votes,

                   "votedByUser" => $vote,

                   "vote" => $voteStatus,

                   "spam" => $spam,

                   "date" => $key->created_at->toDateTimeString()

               ]);

       }

       $collection = collect($replies);

       return $collection->sortBy('votes');

   }

The above code is simple, except for this part:

if(Auth::user()){

               $voteByUser = CommentVote::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();

               $spamComment = CommentSpam::where('comment_id',$key->id)->where('user_id',Auth::user()->id)->first();         

               if($voteByUser){

                   $vote = 1;

                   $voteStatus = $voteByUser->vote;

               }

               if($spamComment){

                   $spam = 1;

               }

           }

In this snippet, I’m first checking whether the user is logged in. Next, I will check whether they have voted for a comment or marked it as spam. If they have voted on a comment, I will save their (up or down) vote.  

Next, I will check whether the user has marked any comment as spam. If  yes, then I will set the boolean `$spam` to true so that the spam comment will not be visible to the user. The `replies()` method will get the replies for that comment.

Create the Routes for Comments

Go to the routes folder and open the web.php file. Add the following routes to it:

Route::get('/{pageId}', function($pageId){

   return view('page',['pageId' => $pageId]);

});

Route::get('comments/{pageId}', 'CommentController@index');

Route::post('comments', 'CommentController@store');

Route::post('comments/{commentId}/{type}', 'CommentController@update');

At this point, the backend of the comment system is done. I will now create the frontend for displaying comments.

Comment Component Using VueJS

For of all, run the following command to install the required dependencies:

npm install

Once done, run the following command to install vue-resource.

npm install -s vue-resource

Now head to resources/assets/js/components and create a new file Comments.vue. Leave the file empty for now. Now go back a step and open app.js to add new reference.

Add the following line after `require(‘./bootstrap’)`:

import VueResource from "vue-resource"

After the Vue instance, add the following line:

Vue.use(VueResource);

And after the `Vue.component` add this line:

Vue.component('comment', require('./components/Comments.vue'));

Create the Comment Component Template

Open the comment.vue file (created earlier) and add the comment template in it. Paste the following code in it:

<template>

<div class="comments-app">

   <h1>Comments</h1>

   <!-- From -->

   <div class="comment-form" v-if="user">

       <!-- Comment Avatar -->

       <div class="comment-avatar">

           <img src="storage/commentbox.png">

       </div>



       <form class="form" name="form">

           <div class="form-row">

               <textarea class="input" placeholder="Add comment..." required v-model="message"></textarea>

               <span class="input" v-if="errorComment" style="color:red">{{errorComment}}</span>

           </div>



           <div class="form-row">

               <input class="input" placeholder="Email" type="text" disabled :value="user.name">

           </div>



           <div class="form-row">

               <input type="button" class="btn btn-success" @click="saveComment" value="Add Comment">

           </div>

       </form>

   </div>

   <div class="comment-form" v-else>

       <!-- Comment Avatar -->

       <div class="comment-avatar">

           <img src="storage/commentbox.png">

       </div>

       <form class="form" name="form">

           <div class="form-row">

               <a href="login"><textarea

                 class="input"

                 placeholder="Add comment..."

                 required></textarea></a>

           </div>

       </form>

   </div>

   <!-- Comments List -->

   <div class="comments" v-if="comments" v-for="(comment,index) in commentsData">

       <!-- Comment -->

       <div v-if="!spamComments[index] || !comment.spam" class="comment">

           <!-- Comment Avatar -->

           <div class="comment-avatar">

               <img src="storage/comment.png">

           </div>



           <!-- Comment Box -->

           <div class="comment-box">

               <div class="comment-text">{{comment.comment}}</div>

               <div class="comment-footer">

                   <div class="comment-info">

                       <span class="comment-author">

                               <em>{{ comment.name}}</em>

                           </span>

                       <span class="comment-date">{{ comment.date}}</span>

                   </div>



                   <div class="comment-actions">

                       <ul class="list">

                           <li>Votes: {{comment.votes}}

                               <a v-if="!comment.votedByUser" v-on:click="voteComment(comment.commentid,'directcomment',index,0,'up')">Up Votes</a>

                               <a v-if="!comment.votedByUser" v-on:click="voteComment(comment.commentid,'directcomment',index,0,'down')">Down Votes</a>

                           </li>

                           <li>

                               <a v-on:click="spamComment(comment.commentId,'directcomment',index,0)">Spam</a>

                           </li>

                           <li>

                               <a v-on:click="openComment(index)">Reply</a>

                           </li>

                       </ul>

                   </div>

               </div>

           </div>

           <!-- From -->

           <div class="comment-form comment-v" v-if="commentBoxs[index]">

               <!-- Comment Avatar -->

               <div class="comment-avatar">

                   <img src="storage/comment.png">

               </div>



               <form class="form" name="form">

                   <div class="form-row">

                       <textarea class="input" placeholder="Add comment..." required v-model="message"></textarea>

                       <span class="input" v-if="errorReply" style="color:red">{{errorReply}}</span>

                   </div>



                   <div class="form-row">

                       <input class="input" placeholder="Email" type="text" :value="user.name">

                   </div>



                   <div class="form-row">

                       <input type="button" class="btn btn-success" v-on:click="replyComment(comment.commentid,index)" value="Add Comment">

                   </div>

               </form>

           </div>

           <!-- Comment - Reply -->

           <div v-if="comment.replies">

               <div class="comments" v-for="(replies,index2) in comment.replies">

                   <div v-if="!spamCommentsReply[index2] || !replies.spam" class="comment reply">



                       <!-- Comment Avatar -->

                       <div class="comment-avatar">

                           <img src="storage/comment.png">

                       </div>



                       <!-- Comment Box -->

                       <div class="comment-box" style="background: grey;">

                           <div class="comment-text" style="color: white">{{replies.comment}}</div>

                           <div class="comment-footer">

                               <div class="comment-info">

                                   <span class="comment-author">

                                           {{replies.name}}

                                       </span>

                                   <span class="comment-date">{{replies.date}}</span>

                               </div>



                               <div class="comment-actions">

                                   <ul class="list">

                                       <li>Total votes: {{replies.votes}}

                                           <a v-if="!replies.votedByUser" v-on:click="voteComment(replies.commentid,'replycomment',index,index2,'up')">Up Votes</a>

                                           <a v-if="!replies.votedByUser" v-on:click="voteComment(comment.commentid,'replycomment',index,index2,'down')">Down Votes</a>

                                           </a>

                                       </li>

                                       <li>

                                           <a v-on:click="spamComment(replies.commentid,'replycomment',index,index2)">Spam</a>

                                       </li>

                                       <li>

                                           <a v-on:click="replyCommentBox(index2)">Reply</a>

                                       </li>

                                   </ul>

                               </div>

                           </div>

                       </div>

                       <!-- From -->

                       <div class="comment-form reply" v-if="replyCommentBoxs[index2]">

                           <!-- Comment Avatar -->

                           <div class="comment-avatar">

                               <img src="storage/comment.png">

                           </div>



                           <form class="form" name="form">

                               <div class="form-row">

                                   <textarea class="input" placeholder="Add comment..." required v-model="message"></textarea>

                                   <span class="input" v-if="errorReply" style="color:red">{{errorReply}}</span>

                               </div>



                               <div class="form-row">

                                   <input class="input" placeholder="Email" type="text" :value="user.name">

                               </div>



                               <div class="form-row">

                                   <input type="button" class="btn btn-success" v-on:click="replyComment(comment.commentid,index)" value="Add Comment">

                               </div>

                           </form>

                       </div>



                   </div>

               </div>

           </div>

       </div>

   </div>

</div>



</template>

In this template, I have created the form for adding comments. I have also added a condition that if the user is logged in, then the button will be visible, else they will be redirected to the login page.

Next are the divs, where comments and the replies will be displayed. I have also added the onclick methods for vote up, vote down and mark spam buttons. In this template, if a user wants to reply to a comment, a form will open up for posting the comment.

Let’s now create a script and add these methods in it.

Create a Comment Component Script

Now after the closing tag of </template>, paste the following lines of code:

<script>

var _ = require('lodash');

export default {

   props: ['commentUrl'],

   data() {

       return {

           comments: [],

           commentreplies: [],

           comments: 0,

           commentBoxs: [],

           message: null,

           replyCommentBoxs: [],

           commentsData: [],

           viewcomment: [],

           show: [],

           spamCommentsReply: [],

           spamComments: [],

           errorComment: null,

           errorReply: null,

           user: window.user

       }

   },

   http: {

       headers: {

           'X-CSRF-TOKEN': window.csrf

       }

   },

   methods: {

       fetchComments() {

           this.$http.get('comments/' + this.commentUrl).then(res => {



               this.commentData = res.data;

               this.commentsData = _.orderBy(res.data, ['votes'], ['desc']);

               this.comments = 1;

           });

           

       },

       showComments(index) {

           if (!this.viewcomment[index]) {

               Vue.set(this.show, index, "hide");

               Vue.set(this.viewcomment, index, 1);

           } else {

               Vue.set(this.show, index, "view");

               Vue.set(this.viewcomment, index, 0);

           }

       },

       openComment(index) {

           if (this.user) {

               if (this.commentBoxs[index]) {

                   Vue.set(this.commentBoxs, index, 0);

               } else {

                   Vue.set(this.commentBoxs, index, 1);

               }

           }

       },

       replyCommentBox(index) {

           if (this.user) {

               if (this.replyCommentBoxs[index]) {

                   Vue.set(this.replyCommentBoxs, index, 0);

               } else {

                   Vue.set(this.replyCommentBoxs, index, 1);

               }

           }

       },

       saveComment() {

           if (this.message != null && this.message != ' ') {

               this.errorComment = null;

               this.$http.post('comments', {

                   page_id: this.commentUrl,

                   comment: this.message,

                   users_id: this.user.id

               }).then(res => {



                   if (res.data.status) {

                       this.commentsData.push({ "commentid": res.data.commentId, "name": this.user.name, "comment": this.message, "votes": 0, "reply": 0, "replies": [] });

                       this.message = null;

                   }



               });

           } else {

               this.errorComment = "Please enter a comment to save";

           }

       },

       replyComment(commentId, index) {

           if (this.message != null && this.message != ' ') {

               this.errorReply = null;

               this.$http.post('comments', {

                   comment: this.message,

                   users_id: this.user.id,

                   reply_id: commentId

               }).then(res => {



                   if (res.data.status) {

                       if (!this.commentsData[index].reply) {

                           this.commentsData[index].replies.push({ "commentid": res.data.commentId, "name": this.user.name, "comment": this.message, "votes": 0 });

                           this.commentsData[index].reply = 1;

                           Vue.set(this.replyCommentBoxs, index, 0);

                           Vue.set(this.commentBoxs, index, 0);

                       } else {

                           this.commentsData[index].replies.push({ "commentid": res.data.commentId, "name": this.user.name, "comment": this.message, "votes": 0 });

                           Vue.set(this.replyCommentBoxs, index, 0);

                           Vue.set(this.commentBoxs, index, 0);

                       }

                       this.message = null;

                   }



               });

           } else {

               this.errorReply = "Please enter a comment to save";

           }

       },

       voteComment(commentId, commentType, index, index2, voteType) {

           if (this.user) {

               this.$http.post('comments/' + commentId + '/vote', {

                   users_id: this.user.id,

                   vote: voteType

               }).then(res => {

                   if (res.data) {

                       if (commentType == 'directcomment') {

                           if (voteType == 'up') {

                               this.commentsData[index].votes++;

                           } else if (voteType == 'down') {

                               this.commentsData[index].votes--;

                           }

                       } else if (commentType == 'replycomment') {

                           if (voteType == 'up') {

                               this.commentsData[index].replies[index2].votes++;

                           } else if (voteType == 'down') {

                               this.commentsData[index].replies[index2].votes--;

                           }

                       }

                   }



               });

           }

       },

       spamComment(commentId, commentType, index, index2) {

           console.log("spam here");

           if (this.user) {

               this.$http.post('comments/' + commentId + '/spam', {

                   users_id: this.user.id,

               }).then(res => {

                   if (commentType == 'directcomment') {

                       Vue.set(this.spamComments, index, 1);

                       Vue.set(this.viewcomment, index, 1);

                   } else if (commentType == 'replycomment') {

                       Vue.set(this.spamCommentsReply, index2, 1);

                   }

               });



           }



       },

   },

   mounted() {

      console.log("mounted");

      this.fetchComments();

   }



}

</script>

Here is a brief explanation of the code above. In the first line, I have required the lodash library to filter comment by vote. Next, I have defined props for commentUrl and then added variables in the data().

Following are the most important methods:

fetchComments()

This method will run when the component is mounted to fetch all the comments for that page. This is why it is used inside `mounted()`.

openComment(index)

This method will open reply comment box for a comment. This method is called by the reply button.

openComment(index) {

           if (this.user) {

               if (this.commentBoxs[index]) {

                   Vue.set(this.commentBoxs, index, 0);

               } else {

                   Vue.set(this.commentBoxs, index, 1);

               }

           }

       }

The method first checks if the user is logged in, and then opens the reply box. If the box is already open, it will close the box.

replyCommentBox(index)

This method is similar to `openComment()`. The difference is that this method opens the comment box for the replies of comments. Check out the image below:

reply comment box

saveComment()

This function will save the user comment.

saveComment() {

           if (this.message != null && this.message != ' ') {

               this.errorComment = null;

               this.$http.post('comments', {

                   page_id: this.commentUrl,

                   comment: this.message,

                   users_id: this.user.id

               }).then(res => {



                   if (res.data.status) {

                       this.commentsData.push({ "commentid": res.data.commentId, "name": this.user.name, "comment": this.message, "votes": 0, "reply": 0, "replies": [] });

                       this.message = null;

                   }



               });

           } else {

               this.errorComment = "Please enter a comment to save";

           }

       }

This function first checks if the comment is null. If it’s null, it will display the error message. If not, it will first bind the params and then send the post request to `comments/`. Once successful, it will push the comment to `commentsData` array so that it can be displayed in the page instantly.

replyComment(commentId, index)

The reply comment saves the reply for the parent comment. It works similar to `saveComment()`. The difference is that it takes `commentId` and the index to bind the reply comment once it is saved.

voteComment(commentId, commentType, index, index2, voteType)

As the name implies, this method is used to vote comments. It first check whether the user is logged in  and then the user could comment. The parameters are defined as:

  • commentId: The id of the comment to vote
  • commentType: The direct comment or reply.
  • Index,index2: Are the indexes of array
  • voteType: Up or Down vote

spamComment(commentId, commentType, index, index2)

This method marks a comment as spam. It only works when the user is logged in. The parameters are defined as:

  • commentId: The id of the comment
  • commentType: The direct comment or reply.
  • Index,index2: Are the the indexes of array

I will now compile the component. For that, run the following command:

npm run dev

Testing Laravel Comment Component

Now open the app in browser. Give it a pageId, for instance “1235” so that the browser URL will be “public/1235”. Once the page opens, you will see the following page:

comment with laravel and vue

Since there are no comment yet, it will be empty.

Now click on the Add Comment and you will be redirected to the login page. Register yourself and then head back to the page to add a comment.

Let’s add a new comment:

add comment

When the page is reloaded, you will see the comment:

Now add replies and more comments to the page.

add replies and more comments

Winding it Up

Vue.JS is an advanced Javascript framework built for designing User Interfaces and single-page applications. Vue is very easy to use and integrates well with Laravel. Here, I have created a Laravel comment system using Vue.js, through which you can save, reply, vote and mark comments spam. 

Let me know if you have any issues in understanding the code. Leave a comment below and I will get back to you.

Share your opinion in the comment section. COMMENT NOW

Share This Article

Inshal Ali

Inshal is a Content Marketer at Cloudways. With background in computer science, skill of content and a whole lot of creativity, he helps business reach the sky and go beyond through content that speaks the language of their customers. Apart from work, you will see him mostly in some online games or on a football field.

×

Get Our Newsletter
Be the first to get the latest updates and tutorials.

Thankyou for Subscribing Us!

×

Webinar: How to Get 100% Scores on Core Web Vitals

Join Joe Williams & Aleksandar Savkovic on 29th of March, 2021.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Want to Experience the Cloudways Platform in Its Full Glory?

Take a FREE guided tour of Cloudways and see for yourself how easily you can manage your server & apps on the leading cloud-hosting platform.

Start my tour

CYBER WEEK SAVINGS

  • 0

    Days

  • 0

    Hours

  • 0

    Mints

  • 0

    Sec

GET OFFER

For 4 Months &
40 Free Migrations

For 4 Months &
40 Free Migrations

Upgrade Now