Building an application with Laravel and Vue

It’s now 5 years since we built our first web application and a lot has happened since then. The very first web app was created from scratch without any framework. We just wrote plain PHP and MySQL, with almost no javascript to create a user friendly interface.

Then we realized it made no sense to write every piece of code ourselves and we started exploring the possibilities to build applications in WordPress. Although we still believe that WordPress is great for websites that mainly consist of content (e.g. blogs), it didn’t have the flexibility we needed to implement the very detailed requests from our clients.

We moved to Laravel and this framework gave us the flexibility we were looking for. We used Laravel for several web apps and especially for the server side it was perfect. The frontend has always been a bit of a challenge. We started with applying jQuery to Laravel’s blade views. Although we managed to create everything we wanted, we ended up with large pieces of code that were hardly maintainable. Time to dive into the world of frontend javascript frameworks. After a short side step to Backbone and React, we finally ended up with Vue JS.

Laravel and Vue

Our most recent web application is a platform about cooking on your own and recipes specifically for 1 person. We are using a combination of Laravel and Vue to create this web app.

In this blog series, we will describe step by step how we developed the application. We assume you already have some knowledge of Laravel, we mainly focus on the Vue part and how you can use it within a Laravel application.

The cooking application we are developing consists of two parts. The first part is an administrator panel where for example recipes can be edited. It is build mainly using Laravel and its blade views. This part is only used by the administrators and only required a simple user interface. Since the admin panel mainly consists of simple CRUD operations, we won’t discuss the details here.

The second part is the public website, which is a Vue app driven by a Laravel API.


Within this setup, the Laravel route/web.php file only has one route for the (non-api part of the) public website: The home url that returns the welcome view:

    return view(‘welcome’)

All other routing for the public website is managed by Vue router, which will be discussed in a follow up post.

Initializing Vue

The welcome view has a very simple setup:

    Some meta tags
    Some links to general stylesheets
    <div id="cooking-cntr" data-url="{{ url('') }}"></div>
    <script src="{{ mix('/js/app.js') }}"></script>
    Some other general JS, for example when you’re using a theme that contains some external JS.

There are two important parts in this blade view:

  • The div with id ‘cooking-cntr’. This is the location where Vue will inject all its templates.
  • The script tag that includes the compiled app.js

In app.js, a new Vue instance is initialized by the next piece of code.


import Vue from 'vue';
import App from './App.vue';
import router from './router';

window.EventBus = new Vue();

const app = new Vue({
    el: '#cooking-cntr',
    template: '<App />',
    components: { App },

The bootstrap.js file comes out of the box in a fresh Laravel install and we only added the babel-polyfill there to make sure that all new ES6 feature also works on older browsers. It might seem a bit overkill to just include it for all users but we are rather safe than sorry.

The bootstrap file furthermore brings jQuery (for the theme to be discussed later) and the Bootstrap css to the party, along with the excellent axios library for requests to the API.

Finally, we setup a baseUrl which is read from the data-url attribute on the main div#cooking-cntr in the welcome view.

We leave it here for this post, but return shortly with the next one in the series covering the initialization of the Vue instance using a component as template (App.vue), adding the router instance in order to use it in all child themes and by including a global event Bus to make it easy to communicate between non parent-child components. The latter is an easy temporary way to do this type of communication. When the app grows, we’ll definitely introduce a Vuex store for state management and this kind of communication.

Mijn Twitter profiel Mijn Facebook profiel
Leonie Derendorp Webdeveloper and co-owner of PLint-sites in Sittard, The Netherlands. I love to create complex webapplications using Laravel! Latest post
Using WordPress as API for Laravel (2) - Connecting Laravel to WordPress

Leave a Reply

Your email address will not be published. Required fields are marked *