Laravel wasn’t created or designed with the concept of rich Javascript single page applications in mind. This means that, unlike the server side, the front-end is not opinionated at all.

The result is that we are left to decide on an approach that works for whichever project we are working on.

For this example, lets say my project is a well established, old-school, Laravel based Website. We’re going to add a VueJS SPA in as a new user dashboard.

Some key features we would like:

  • Must use Webpack with the Vue CLI - this keeps the SPA easier to maintain and 3rd party components can be easily integrated
  • Must use the existing Laravel auth and session to control access to the new SPA - not worrying about auth in a SPA is pretty much the definition of awesome

First step is to include a new VueJS SPA setup somewhere in your build cycle. Create a folder somewhere good for the new dashboard. Maybe under “resources” or even in the root of your project. This code can be its own Git repository and can be treated as a submodule.

Second step is to set up you build process. Whatever you are using to build your front-end resources - add a step to install & compile the SPA. Let it create the “dist” folder. Your build routine should then copy the contents of the “dist” folder to a folder with the path’s name inside the “public” folder. For example, if we will access the new dashboard on “/dashboard” then the folder you copy your “dist” files to will be “public/dashboard/”. The last build step is to copy the “dist/index.html” file to a new file inside your views folder. An option would be to copy it to “resources/views/dashboard/index.blade.php”. Notice the rename to “.blade.php”.

Third step is to set up a route and/or controller to serve this index blade for all requests that hit “/dashboard” and any path under this path. something like:

Route::get('/dashboard/{all?}' ...
)->where(['all' => '[0-9a-zA-Z\/]+']);

Use whichever regex pattern makes sense for you and be sure to add whichever auth and session middleware you want to enforce. Handling GET only should be fine, but be flexible to change that to “any” if you want.

Final step is to configure your VueJS SPA to serve from “/dashboard”. Build it and test your setup.

The end result is that when a user visits “/dashboard” or any path under “/dashboard/*” that is not an existing file, the SPA’s index.html file is loaded. This in turn loads the static files from the “/public/dashboard” folder and your SPA is integrated into your Laravel Website.

Next, you’re going to need to figure out a new API for your SPA. But, forcing your SPA to load through Laravel’s session & auth should make the API a little simpler to deal with. That is until you decide to grow your Website to a true SPA & API driven system.