# Building a Vue SPA with Laravel PART 1

Building a Vue single page application (SPA) with Laravel is a beautiful combination for building clean API-driven applications. In this tutorial, we show you how to get up and running with Vue router and a Laravel backend for building a SPA. We will focus on the wiring up all the pieces needed, and then in a follow-up tutorial, we will further demonstrate using Laravel as the API layer.

The primary flow of how an Vue SPA works with Laravel as a backend is as follows:

* The first request hits the server-side Laravel router
* Laravel renders the SPA layout
* Subsequent requests leverage the `history.pushState` API for URL navigation without a page reload

Vue router can be configured to use history mode or the default hash-mode, which uses the URL hash to simulate a full URL so the page won’t reload when the URL changes.

We will use history mode, which means we need to configure a Laravel route that will match all possible URLs depending on which route the user enters the Vue SPA. For example, if the user refreshes a `/hello` route, we’ll need to match that route and return the Vue SPA application template. The Vue Router will then determine the route and render the appropriate component.

### Installation

To get started, we will create a new Laravel project and then install the Vue router NPM package:

```
1laravel new vue-router2cd vue-router34# Link the project if you use Valet5valet link67# Install NPM dependencies and add vue-router8yarn install9yarn add vue-router # or npm install vue-router
```

We have a Laravel installation and the `vue-router` NPM package ready to go. Next, we’ll configure the router and\
define a couple of routes and components.

### Configuring Vue Router

The way that Vue Router works is that it maps a route to a Vue component and then renders it within this tag in the application:

```
1<router-view></router-view>
```

The router view is within the context of the Vue application component that surrounds the entire application. We will come back to the `App` component momentarily.

First, we are going to update the main JavaScript file `resources/assets/js/app.js` and configure Vue router. Replace the contents of the `app.js` file with the following:

```
 1import Vue from 'vue' 2import VueRouter from 'vue-router' 3 4Vue.use(VueRouter) 5 6import App from './views/App' 7import Hello from './views/Hello' 8import Home from './views/Home' 910const router = new VueRouter({11    mode: 'history',12    routes: [13        {14            path: '/',15            name: 'home',16            component: Home17        },18        {19            path: '/hello',20            name: 'hello',21            component: Hello,22        },23    ],24});2526const app = new Vue({27    el: '#app',28    components: { App },29    router,30});
```

We have a few files that we need to create, but first, let’s cover the contents of `app.js`:

* We import and install the `VueRouter` plugin with `Vue.use()`
* We import three Vue components:
  * an `App` component that is the outermost application component,
  * A `Hello` component that maps to the `/hello` route
  * A `Home` component that maps to the `/` route
* We construct a new `VueRouter` instance that takes a configuration object
* We make Vue aware of the `App` component by passing it to the `components` property in the Vue constructor
* We inject the `router` constant into the new Vue application to get access to `this.$router` and `this.$route`

The `VueRouter` constructor takes an array of routes, where we define the path, the name (just like Laravel’s named route), and the component that maps to the path.

I like to move my route definitions into a separate routes module that I import, but for the sake of simplicity we’ll define the routes within the main application file.

In order for Laravel mix to run successfully, we need to define the three components:

```
1mkdir resources/assets/js/views2touch resources/assets/js/views/App.vue3touch resources/assets/js/views/Home.vue4touch resources/assets/js/views/Hello.vue
```

First, the `App.vue` file is the outermost container element for our application. Inside this component, we’ll define an application heading and some navigation using Vue Router’s `<router-link/>` tag:

```
 1<template> 2    <div> 3        <h1>Vue Router Demo App</h1> 4 5        <p> 6            <router-link :to="{ name: 'home' }">Home</router-link> | 7            <router-link :to="{ name: 'hello' }">Hello World</router-link> 8        </p> 910        <div class="container">11            <router-view></router-view>12        </div>13    </div>14</template>15<script>16    export default {}17</script>
```

The most important tag in our `App` component is the `<router-view></router-view>` tag, which is where our router will render the given component that matches the route (i.e. `Home` or `Hello`).

The next component we need to define is located at `resources/assets/js/views/Home.vue`:

```
1<template>2  <p>This is the homepage</p>3</template>
```

Lastly, we define the `Hello` component located at `resources/assets/js/views/Hello.vue`:

```
1<template>2  <p>Hello World!</p>3</template>
```

I like separating my reusable components from my view-specific components by organizing my views into the `resources/assets/js/views` folder and my truly reusable components in `resources/assets/js/components`. This is my convention, and I find it works well so I can easily separate which components are intended to be reusable and which components are view-specific.

We have everything we need to run our Vue application as far as the frontend is concerned! Next, we need to define the backend route and the server-side template.

#### The Server-Side

We leverage an application framework like Laravel with a Vue SPA so that we can build a server-side API to work with our application. We can also use Blade to render our application and expose environment configuration through a global JavaScript object, which is convenient in my opinion.

In this tutorial, we aren’t going to build out an API, but we will in a follow-up. This post is all about wiring up the Vue router.

The first thing we’ll tackle on the server-side is defining the route. Open the `routes/web.php` file and replace the welcome route with the following:

```
 1<?php 2 3/* 4|-------------------------------------------------------------------------- 5| Web Routes 6|-------------------------------------------------------------------------- 7| 8| Here is where you can register web routes for your application. These 9| routes are loaded by the RouteServiceProvider within a group which10| contains the "web" middleware group. Now create something great!11|12*/1314Route::get('/{any}', 'SpaController@index')->where('any', '.*');
```

We define a catch-all route to the `SpaController` which means that any web route will map to our SPA. If we didn’t do this, and the user made a request to `/hello`, Laravel would respond with a 404.

Next, we need to create the `SpaController` and define the view:

```
1php artisan make:controller SpaController
```

Open the `SpaController` and enter the following:

```
 1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6 7class SpaController extends Controller 8{ 9    public function index()10    {11        return view('spa');12    }13}
```

Lastly, enter the following in `resources/views/spa.blade.php`:

```
 1 2<html lang="en"> 3<head> 4    <meta charset="UTF-8"> 5    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6    <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7    <title>Vue SPA Demo</title> 8</head> 9<body>10    <div id="app">11        <app></app>12    </div>1314    <script src="{{ mix('js/app.js') }}"></script>15</body>16</html>
```

We’ve defined the required `#app` element which contains the `App` component that Vue will render, along with rendering the appropriate component based on the URL.

### Running the Application

The foundation is in place for building an SPA with Vue and Vue Router. We need to build or JavaScript to test it out:

```
1yarn watch # or npm run watch
```

If you load up the application in your browser you should see something like the following:

[![Vue Router Laravel Demo App](https://i0.wp.com/wp.laravel-news.com/wp-content/uploads/2018/01/vue-router-app-screenshot.png?resize=525%2C201)](https://i0.wp.com/wp.laravel-news.com/wp-content/uploads/2018/01/vue-router-app-screenshot.png)

### Going Forward

We have the skeleton for a Vue SPA that we can start building using Laravel as the API layer. This app still has much to be desired that we will cover in a follow-up tutorial:

* Define a catch-all 404 route on the frontend
* Using route parameters
* Child routes
* Making an API request from a component to Laravel
* Probably much more that I’m not going to list here…

The goal of this tutorial was the lay the groundwork for showing you how easy you can start an SPA with Vue Router. If you’re not familiar with it, check out the [Vue Router documentation](https://router.vuejs.org/en/essentials/getting-started.html)

Now, onward to [Part 2](https://laravel-news.com/building-vue-spa-laravel-part-2/)!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://learnmagento.gitbook.io/vuejs/building-a-vue-spa-with-laravel-part-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
