Vue-Router not rerouting in Single Page Application (Vue/Laravel)

I am trying to get vue-router to work in a Vue.js/Laravel project. I have the following simple pages:

home page:

enter image description here

about page (scrolled down in single page):

enter image description here

Made from these files:

welcome.blade.php:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=WeakMap"></script>
  <title>title</title>
</head>
<body id="body">
  <div id="app">
    <app></app>
  </div>
</body>
<script src="{{ mix('js/app.js') }}"></script>
</html>

app.vue:

<template>
  <div class="container">
    <main>
      <home></home>
      <about></about>
    </main>
  </div>
</template>

<script>
import About from "./about"
import Home from "./home";

export default {
  name: "app",
  components: {
    About,
    Home,
  }
}
</script>

<style lang="scss">
</style>

home.vue:

<template>
  <section class="home" style="background-color: yellow; height: 100vh">
    <h1>Home Page</h1>
  </section>
</template>

<script>
export default {
  name: "home"
}
</script>

<style scoped lang="scss">
</style>

about.vue:

<template>
  <section class="about" style="background-color: green; height: 100vh">
    <h2>About Page</h2>
  </section>
</template>

<script>
export default {
  name: "about"
}
</script>

<style scoped lang="scss">
</style>

web.php:

<?php

use Illuminate\Support\Facades\Route;


Route::get('/', function () {
  return view('welcome');
});

app.js:

require('./bootstrap')

import Vue from "vue"
import App from "../vue/app"
import router from "./router";

const app = new Vue({
    el: "#app",
    components: { App },
    router
})

router.js:

import Vue from "vue";
import VueRouter from "vue-router";

import Home from "../vue/home";
import About from "../vue/about";

Vue.use(VueRouter);

export default new VueRouter({
    mode: "history",
    routes: [
        { path: "/", component: Home},
        { path: "/about", component: About}
    ]
});

Now, if I add <router-view></router-view> to app.vue like this:

<template>
  <div class="container">
    <main>
      <home></home>
      <about></about>
    </main>
  </div>
  <router-view></router-view>
</template>

The site doesn't load at all and the browser console shows no errors:

enter image description here

Path localhost:3000/about shows an 404 Error:

enter image description here

What am I doing wrong?

Upvotes: 1

Views: 259

Answers (2)

dave
dave

Reputation: 2901

In Laravel you need a catch-all route that redirects all routes to your Vue project:

Create a new controller called something like VueController, then direct all your routes in Laravel to it:

Route::get('/{any}', 'VueController@index')->where('any', '.*');

Then in your VueController return your welcome blade:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class VueController extends Controller
{
    public function index()
    {
        return view('welcome');
    }
}

Upvotes: 1

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23510

Did you try to define base in router:

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

export default router;

Then in app:

<template>
  <div class="container">
   <nav>
     <router-link
      to="/"
      tag="a"
      >Home</router-link>
     <router-link
      to="/about"
      tag="a"
      >About</router-link>
    </nav>
  </div>
  <router-view></router-view>
</template>

Upvotes: 1

Related Questions