so I’m developing a website/webapp in Laravel 5.3, and Vue 2. SEO is important, so I’m wanting to keep the frontend/crawable section of the site in Laravel + Blade, and only small non necessary sections in Vue 2.0, so I’ve not got to use Ajax to load the page content, and allowing crawlers like Google to crawl and index the site. (AFAIK, Google does load JS, but doesn’t wait for Ajax to load, so it’s hit/miss).
However, on the backend, I want to go fully SPA with Vue and VueRouter.
How do I best separate the two?
I want my backend to be accessible via /manager
My solution so far is to:
# routes.php
### Laravel/Frontend routes go here (before SPA) ###
Route::get('/manager/{spaPlage?}', ['middleware' => 'auth', function () {
return view('manager.index');
}])->where(['spaPlage' => '.*'])->name('manager.index');
and then in Vue, I use:
const routes = [
{ path: '/', name: 'dashboard.index', component: require('./pages/manager/Dashboard.vue') },
{ path: '/categories', name: 'categories.index', component: require('./pages/manager/categories/Index.vue') },
{ path: '/category/:id', name: 'category', component: require('./pages/manager/categories/Category.vue') }
];
const router = new VueRouter({
routes,
base: '/manager'
})
const app = new Vue({
el: '#app',
router
...
Which does work. However, it doesn’t feel right. Because the view router still loads on my frontend (appends hash/hashbang).
So, is there a better way to separate my Laravel frontend with my Vue SPA backend?
2
Answers
For anyone who comes across this, I wasn't able to find anything on disabling VueRouter for specific links. I don't think it's possible, also, it's probably not worth the hassle.
So I've decided to re-write all my codebase to be a SPA. It's about time, and there's no real reason not to. I'm using Prerender.io's self hosted service for pre-rendering for SEO, etc.
Just to clarify some misconceptions for anyone in the future.
Google can crawl JS based front end websites without the need to pre-render or server-side render. With one caveat, Google uses Chrome 41 to crawl and render the site, so your javascript has to be polyfilled at least well enough to support Chrome 41 features (or at least your Vue-based data needs to be polyfilled to support Chrome 41). I haven’t had any trouble just using babel thus far.
This is backwards. If you are doing this, don’t. Laravel should be your backend & frontend (via blade + bootstrap + Vue/react), or your backend only. Vue.js is a frontend framework and shouldn’t be used as a “backend.” All your database queries, authentication, calculations, emailing, etc. should be handled by Laravel. Laravel is great for backend work and it’s completely reasonable to code an entire API up with laravel and use Vue exclusively for front end. Sure you might be able to hack it together and make it somehow work, but you shouldn’t, and you’d just be creating extra headache for yourself for no reason.
But to also answer the question, because there is a case to be made for a website that has only part of it’s site as an SPA (maybe the blog is an SPA site, but is complete separate from the “about us”, “contact us”, etc like pages (for instance, you might be revamping a website in parts, and would like to roll out updated pages over time instead of tackling everything at once). In this case you can specify specific routes for Vue Router to run on, and all others will be handled by laravel.
This would allow Vue Router to handle everything in the
DIR
sub directory, but allow other routes to coexist along side of it.But if your application requires Vue Router to have access at the root domain, then just put that at the very end of your routes file, because when route matching is done, it quits after the first match. So by placing it at the end of your routes file, you are essentially using it as a “catch all” for any routes not specified above it. Think of it like returning early.