Reputation: 3209
I have a Laravel 5.2 setup running in Homestead and using Vue.js router to build an SPA. I'm trying to completely remove the #hash from the URL which I know can be done, but I keep getting errors:
I've added rewrite ^(.+)$ /index.html last;
to my vhosts file in Homestead:
server {
listen 80;
listen 443 ssl;
server_name app.myproject.dev;
root "/home/vagrant/Code/vibecast/app.myproject.com/public";
rewrite ^(.+)$ /index.html last;
index index.html index.htm index.php;
charset utf-8;
...
}
When I restart and open a page I get a 500 Internal Server Error
.
Is there anything I need added to routes in Laravel?
var router = new VueRouter({
hashbang: false,
history: true,
linkActiveClass: "active"
})
I can get it working without the #hash (or the modified hosts file) when navigating around, but fails when I reload a page.
Upvotes: 6
Views: 16835
Reputation: 21
export default new Router({ mode: 'history', // https://router.vuejs.org/api/#mode linkActiveClass: 'active', })
Upvotes: 2
Reputation: 86
Add the below line to your Laravel web.php
Route::get('/{vue?}', 'App\Http\Controllers\AppController@index')->where('vue', '[\/\w\.-]*');
Vue-Router
const router = new VueRouter({
mode: 'history',
routes,
})
Upvotes: 0
Reputation: 3209
I've managed to find a solution, via Matt Stauffer's demo app. First, no need to update vhosts file. Just need to update the SPA/Vue.js route in routes.php
to:
Route::get('/{vue?}', 'AppController@spa')->where('vue', '[\/\w\.-]*');
If you have an admin panel and do not want to consider its prefix
Route::get('/{vue?}', 'AppController@spa')->where('vue','^(?!panel).*$');
And of course initialise the Vue.js router like so:
const router = new VueRouter({
history: true,
hashbang: false,
linkActiveClass: 'active'
})
router.mode = 'html5'
Ref: https://github.com/mattstauffer/suggestive/blob/master/app/Http/routes.php#L9
Upvotes: 7
Reputation: 709
You can make Vue Router and Laravel Router work together nicely by making the following changes:
At the end of your routes/web.php
add the next lines:
Route::get('{path}', function() {
return view('your-vuejs-main-blade');
})->where('path', '.*');
You need to add this at the end of file because you need to preserve the previously declared laravel routes in order to work properly and not be overwritten by the 404 page or vue-router's paths.
In your Vue router's config use the following:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
let router = new Router({
mode: 'history', //removes # (hashtag) from url
base: '/',
fallback: true, //router should fallback to hash (#) mode when the browser does not support history.pushState
routes: [
{ path: '*', require('../components/pages/NotFound.vue') },
//... + all your other paths here
]
})
export default router
However, when navigating between laravel and vue-router, you need to keep in mind that leaving vue-router's page to a laravel page you must use a window.location.href
code, an <a>
tag or some sort of programmatic navigation in order to fully exit Vue-router's instance.
Tested this with Laravel 5.5.23, Vue 2.5.9, Vue-Router 3.0.1
Upvotes: 9
Reputation: 11
Laravel router
Route::any('{all}', function () {
return view('welcome');})->where(['all' => '.*']);
Vue-router
export default new Router({
routes: [
{ path: '/', name: 'Home', component: HomeView },
{ path: '/category', name: 'Category', component: CategoryView },
{ path: '/topic', name: 'Topci', component: TopicView }
],
mode: 'history'
})
Upvotes: 1
Reputation: 4155
You need to set the router mode to html5
RE: http://vuejs.github.io/vue-router/en/api/properties.html
So your new code would be like:
var router = new VueRouter({
hashbang: false,
history: true,
linkActiveClass: "active"
})
router.mode = 'html5'
Upvotes: 2