Site Cloner PHP Script
Bargain Hunter PHP Script
Job Hunter PHP Script
Site Login and Access Control PHP Script

After spending many part time hours ‘Googling’ for solutions to adding Vuejs to older and the latest Laravel 5.8 installation, I felt the necessity to publish this complete tutorial for adding Vuejs to Laravel in order to build SPA (Single Page Applications).

In modern times, Laravel 5.8 comes shipped with Vuejs. With older versions which may be downloaded, like admin templates from Codecanyon, we need to perform other operations to include it to an older app.

So, let’s separate the Laravel 5.8 from the older versions. Nevertheless, the same operations for older versions can be implemented to Laravel 5.8 too because it simply involves downloading Vuejs and Vuejs router, adding the files and using them.

Laravel 5.8

Since Laravel 5.8 comes shipped with Vuejs, we can add it and use it via the following commands which will install the node modules listed in the package.json file.

  • Step1: composer update
  • Step2: rm -rf node_modules
  • Step3: npm cache clean --force
  • Step4: npm install
  • Step5: npm outdated
  • Step6: npm install
  • Step7: npm run dev
  • Step 8 npm run watch

Once we have that, all we really need to do is make changes to the file resources/js/app.js

When we run the command ‘npm run watch’, we can take advantage of it being recompiled after we make changes to the file in order to view our results. With that said, the code below can be used to make it run as a single page application. Keep in mind, this example is used on the default template that comes shipped with Laravel.

Routes routes/web.php

The files routes/web.php needs the following line(s) to be able to use an SPA. We can use it for the base url or create a path with vuejs to run the SPA.

Route::get('/vuejs/{any}', 'SinglePageController@index')->where('any', '.*');
Route::get('/{any}', 'SinglePageController@index')->where('any', '.*');
After we add the route, we need to make the SinglePageController. We can make the controller with the following command.The controller will be located in the folder app/Http/Controllers. Alternatively, we could always create it manually by creating a file called SinglePageController.php. php artisan make:controller SinglePageController
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SinglePageController extends Controller
{
    //
    public function index() {
        return view('app');
    }
}
Now that we have our controller that returns the view file app.blade.php, we need to make that file and ensure it has the code below that will handle the SPA inside the div tag with the id equal to ‘app’. With the code block, the router-link handles the links while the is where the actual custom content will be located.
<div id="app">

<router-link to="/vuejs/foo">Page Foo</router-link>
<router-link to="/vuejs/bar">Page Bar</router-link>

<router-view></router-view>

</div>

The code below is a simple boilerplate for app.js

require('./bootstrap');

import Vue from 'vue'
import VueRouter from 'vue-router';
window.Vue = require('vue');

Vue.use(VueRouter);

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

const test = Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const testbar = Vue.component('example-component2', require('./components/ExampleComponent2.vue').default);

const router = new VueRouter({
routes: [
{ path: '/vuejs/foo', component: test, name: 'Foo' },
{ path: '/vuejs/bar', component: testbar, name: 'Bar' },
{ path: 'vuejs/foo', component: test, name: 'Foo' },
{ path: 'vuejs/bar', component: testbar, name: 'Bar' },
{ path: 'foo', component: test, name: 'Foo' },
{ path: 'bar', component: testbar, name: 'Bar' }

],

mode: 'history'

});

const app = new Vue({
el: '#app',
router
});

With the above, we can name and keep our separate components for each page in the resources/js/components folder. That is it, we now have a basic SPA.

Older Laravel Versions

Like Laravel 5.8, we need to define routes in our file web.php. Two routes are shown below.
Route::get('/vuejs/{any}', 'SinglePageController@index')->where('any', '.*');
Route::get('/{any}', 'SinglePageController@index')->where('any', '.*');
Then, we need our controller for a single page app for which we can create using the basic command below.
php artisan make:controller SinglePageController
Once our controller is built, we simply load a view file called app.blade.php which will reside as resources/view/app.blade.php. The next block is code that loads that view.
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SinglePageController extends Controller
{
    //
    public function index() {
        return view('app');
    }
}
Next, we need the block below which handles the single page application links and content.
<div id="app">

    <router-link to="/vuejs/foo">Foo</router-link>
    <router-link to="/vuejs/bar">Bar</router-link>

    <router-view></router-view>

</div>

For the older Laravel installs, we can go to the vuejs website and download vue.min.js and vue-router.js.

Then, we can add place these scripts in the public/assets/js folder and add the reference to them in our blade files using:

‘<script type=text/javascript” src=”{{ asset(‘assets/js/vue.min.js’) }}”></script>’ and
‘<script type=text/javascript” src=”{{ asset(‘assets/js/vue-router.js’) }}”></script>’ .

Alternatively, we could use a path like:

‘<script type=text/javascript” src=”{{ ‘/js/vue.min.js’) }}”></script>’ too. These files can go below the footer scripts.

 <script>
     
        const Home = { template: '<div>home</div>' }
        const Foo = { template: '<div>foo</div>' }
        const Bar = { template: '<div>bar</div>' }

        const router = new VueRouter({
            routes: [
                { path: '/admin/vue', component: Home, name: 'Home' },
                { path: '/admin/vue/foo', component: Foo, name: 'Foo' },
                { path: '/admin/vue/bar', component: Bar, name: 'Bar' }
            ],
            mode: 'history'          
        });

        const app = new Vue({

            el: '#app',
            data: {message: 'Hello World'},
            router           
        });

    </script>

Conclusion

So there we are, we now have a couple of methods for adding Vuejs into our latest and older Laravel apps so we can build single page applications without a fuss.

After Googling and reading many sites about Laravel multi-tenant, multisite, or whatever you want to call it, I decided I wanted a simple DIY method to add subfolders which could have its own database.

I did not want to mess around with apache, .htaccess…rather just add and modify a few lines of code here and there. With that said, here are some details regarding how we can reach our end goal. This tutorial reached those results using Laravel 5.7

With this minor changes below, we can easily have subdirectories use a private database. Thus, each subfolder is completely unique for user, passwords and content.

We can take this farther and write a simple script to automatically make these changes with a click of the mouse for any new subfolder we wish to create.

1. Add a second .env file with new name
2. Add a second routes file and name it like web2.php. These routes will be like the original file except the routes will include the subdirectory
3. Make changes to bootstrap/app.php. This code checks for the subfolder 'test' and returns the appropriate .env file.  

Changes are shown below.

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$cur_dir = basename(dirname($_SERVER['REQUEST_URI']));


$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']
    === 'on' ? "https" : "http") . "://" .
    $_SERVER['HTTP_HOST'] .$_SERVER['REQUEST_URI'];

// Display the complete URL

$urlParts = explode('/', str_ireplace(array('http://', 'https://'), '', $url));

switch(array_pop(explode($_SERVER['HTTP_HOST'], $urlParts[1]))){
    case 'test':
        $app->loadEnvironmentFrom('.env.sub1');
        break;
    default:
        $app->loadEnvironmentFrom('.env');
        break;
};
4. Make changes to app\Providers\RouteServiceProvider.php
Change the map method by adding the new method which will include the new routes file. This web route method call for $this->mapWebRoutes2(); must be above the original $this->mapWebRoutes();

Notice a the new method calling the web2.php route file too shown last.

public function map()
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes2();
        $this->mapWebRoutes();
    } 

protected function mapWebRoutes2()
    {
        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web2.php'));
    }