Work Laravel 5.3 + Vue.JS 2.0 - Make VueRouter's History Mode Play Nicely with Laravel's Routes

Laravel 5.3 + Vue.JS 2.0 - Make VueRouter's History Mode Play Nicely with Laravel's Routes

21st Oct, 2016 | Work

I have to admit I have really been having a ball with VueJs and Laravel these last few weeks. Logic is beautiful.

In that spirit, I will quickly show you how I got my VueRouter's history mode to work well with Laravel's routes. The history mode of the VueRouter allows us to get rid of the '#' in URLs whilst maintaining page history - which of course means that our application is going to get confused especially when you reload the page and Laravel + VueJs do a Trumpillary.

Luckily, we can always check whether it's Laravel or VueJs making a request by using the $request->ajax() method.

First of all, let us instruct our VueRouter to use the history mode rather than the default hash mode:

 

var router = new VueRouter({
    mode: 'history',
    base: subscribersLinks.baseUri,
    linkActiveClass: 'active',
    routes: [
        { path: '/all', name: 'subscribers.index', component: SubscribersList },
        { path: '/:id(\\d+)/edit', name: 'subscribers.edit', component: SubscribersEdit },
        { path: '/:mList(\\d+)/mailing-list', name: 'subscribers.mailing_list', component: SubscribersList },
        { path: '/new', name: 'subscribers.new', component: SubscribersNew },
        { path: '/batch-import', name: 'subscribers.import', component: SubscribersImport },
        { path: '/trash', name: 'subscribers.trash', component: SubscribersTrash },
        { path: '*', redirect: { name: 'subscribers.index' } }
    ]
});

 

Pay attention to the mode part and also the last route defined. That is a fallback for when the requested route does not exist. Here we instruct VueJs to server the subscribers.index route in such a case.

On the Laravel side, whenever the $request->ajax() is false, the same route will always capture the request. So, we can safely define a catch-all route to redirect such traffic to the index() method of our resource controller:

 

Route::group(['middleware' => 'auth'], function () {
    if ( ! request()->ajax() ) {
        Route::get('subscribers/{vue?}', 'SubscriberController@index')->where('vue', '[\/\w\.-]*');
    }
});

Route::resource('subscribers', 'SubscriberController');
Route::put('subscribers/{option}/quick-edit', 'SubscriberController@quickUpdate');

 

Remember the routes listed higher in the route file take precedence over those lower. So first we are checking to see how the request is coming in and if it's not via AJAX, we kinda override the routes that server content to VueJs. Effectively, we are telling our app, first concentrate on initialising the index page (or view) for our app and after that, you may proceed to do other things.
Lovely.

 

 

 

 

Comments