rces/js/app.js ` file using the [ @vite()
Blade directive ](https://laravel.com/docs/10.x/vite#loading-your-scripts-and-
styles) .

    
    
    <head>
        @vite(['resources/js/app.js'])
    </head>
    
    <body>
        <div id="app"></div>
    </body>

With just that, we got Vue working with Laravel 🥳 We can test it by running `
npm run dev ` and ` php artisan serve `

![](https://blog.vueschool.io/wp-content/uploads/2024/01/vueschool-rocks-
test.png)

We still need to make it a dynamic single-page application. To achieve this,
we will [ use Vue Router ](https://vueschool.io/courses/vue-router-for-
everyone) . Let’s create a new file ` ./resources/js/router.js ` to define the
router :

    
    
    import { createRouter, createWebHistory } from "vue-router";
    
    const routes = [];
    
    export default createRouter({
        history: createWebHistory(),
        routes,
    });

Next step, integrate the router we just created with our Vue instance inside `
./resources/js/app.js ` file

    
    
    import "./bootstrap";
    import router from "./router/router";
    import { createApp } from "vue";
    
    import App from "./App.vue";
    
    createApp(App).use(router).mount("#app");

So, now we need a ` ./resources/js/Pages/ ` directory that will contain our
route components. We first create ` ./resources/js/Pages/HomeRoute.vue ` with
a ` router-link ` to test internal navigation when we’re done:

    
    
    <template>
        <div>
            <h1>HOME</h1>
            <router-link to="/test"> Take me to Test page </router-link>
        </div>
    </template>

Then we create ` ./resources/js/Pages/TestRoute.vue `

    
    
    <template>
        <h1>I'm here to test!</h1>
    </template>

Next, Lazy load the new route components in the router’s file `
./resources/js/router.js `

    
    
    import { createRouter, createWebHistory } from "vue-router";
    
    const routes = [
        {
            path: "/",
            component: () => import("./Pages/HomeRoute.vue"),
        },
        {
            path: "/test",
            component: () => import("./Pages/TestRoute.vue"),
        },
    ];
    
    export default createRouter({
        history: createWebHistory(),
        routes,
    });

It’s worth mentioning that we can use ` [unplugin-vue-router ` package]( [
https://github.com/posva/unplugin-vue-router?tab=readme-ov-file
](https://github.com/posva/unplugin-vue-router?tab=readme-ov-file) ) to enable
file based routing feature. But for this tutorial, we’ll stick with the
official Vue Router approach.

Finally, we tweak the code inside the Vue entry file to make it dynamic.
Luckily, Vue Router provides [ RouterView built-in component
](https://router.vuejs.org/guide/advanced/router-view-slot.html) , which
exposes slots that we can leverage to dynamically render route components.

Head to ` ./resources/js/App.vue ` and modify it as follows:

    
    
    <template>
        <router-view v-slot="{ Component, route }">
            <div :key="route.name">
                <Component :is="Component" />
            </div>
        </router-view>
    </template>

Now if we hit ` npm run dev ` and ` php artisan serve ` in the terminal, click
on the link to navigate to ` /test ` , we will find it working as expected
with client-side navigation. But here’s the catch, if we do a hard refresh,
Laravel will return a “404 Not Found” error. This is happening because we
don’t have web routes defined in Laravel.

To overcome this challenge, we can head to ` ./routes/web.php ` and define a
single route that will catch all valid routes and use the Blade entry file
which contains our Vue application.

    
    
    Route::get('/{vue_capture?}', function () {
        return view('welcome');
    })->where('vue_capture', '[\/\w\.-]*');

With that done, hard refresh won’t ruin our application anymore. However, it’s
worth mentioning that 404 pages still need to be handled using Vue Router. You
can follow the instructions