Create a SPA with Laravel and Nuxt
Tags: spa, api, laravel, nuxt
Published: 2018-02-13 20:54:40

---
title: Create a SPA with Laravel and Nuxt
published: true
description: Tutorial to create a single page application with Laravel and Nuxt
tags: spa, api, laravel, nuxt
---

In this tutorial we'll use [Laravel](https://laravel.com/) as an API and [Nuxt](https://nuxtjs.org/) as a Single Page Application. They can work together, but it's not an easy task at first. If you already tried, getting HMR to seamlessly work is a pain! For that reason I created [laravel-nuxt](https://github.com/skyrpex/laravel-nuxt) and [laravel-nuxt-js](https://github.com/skyrpex/laravel-nuxt-js).

There are more reasons to use these packages, such as when using [Laravel Passport](https://laravel.com/docs/5.5/passport) and the `CreateFreshApiToken`. The middleware will create an `api_token` cookie on `web` routes that use the `get` http verb, and that's a problem if you're not serving your SPA from within Laravel.

# Getting started

## Install Laravel

Let's start with fresh new Laravel installation:

```bash
composer create-project laravel/laravel spa
```

Go inside the `spa` directory with your terminal.

## Install laravel-nuxt (for PHP)

```bash
# cd spa
composer require pallares/laravel-nuxt
```

This package will be autodiscovered. If you're using old versions of Laravel, just add the service provider in `config/app.php` file:

```php
<?php
return [
    // ...
    'providers' => [
        // ...
        Pallares\LaravelNuxt\LaravelNuxtServiceProvider::class,
    ],
];
```

Add a fallback route that will render the SPA page in `routes/web.php` file. Be sure to remove the default route that comes with the framework:

```php
<?php
// Route::get('/', function () {
//     return view('welcome');
// });

Route::get(
    '{uri}',
    '\\'.Pallares\LaravelNuxt\Controllers\NuxtController::class
)->where('uri', '.*');
```

Now, your backend is ready to serve the compiled assets that Nuxt will generate for you. Every route that would return a 404 now will serve our SPA page.

## Install laravel-nuxt (for JS)

It's time to install the JS package. Replace your `package.json` file with this:

```json
{
    "private": true,
    "scripts": {
        "start": "laravel-nuxt dev",
        "build": "laravel-nuxt build"
    },
    "dependencies": {
        "laravel-nuxt": "^1.0.0"
    }
}
```

Install the dependencies:

```bash
npm install
```

The `laravel-nuxt` package will install Nuxt for you, along with [Vue](https://github.com/vuejs/vue), [vue-router](https://github.com/vuejs/vue-router), [@nuxtjs/axios](https://github.com/nuxt-community/axios-module), etc. Let's create the `nuxt.config.js` file:

```js
const laravelNuxt = require("laravel-nuxt");

module.exports = laravelNuxt({
  // Options such as mode, srcDir and generate.dir are already handled for you.
  modules: [],
  plugins: [],
});
```

From now on, Nuxt will look for the source files in the `resources/nuxt` directory.

Create a hello world route in `resources/nuxt/pages/index.vue`:

```html
<template>
  <h1>Hello {{ name }}!</h1>
</template>

<script>
export default {
  data: () => {
    return { name: 'world' };
  },
};
</script>
```

Finally, run:

```bash
npm start
```

Go to http://localhost:8000. You should see this: ![hello-world-picture](https://cdn.pbrd.co/images/H7v0Mzl.jpg)

That's it! Laravel artisan's server and Nuxt's dev server are up and working together transparently. Try editing your home page now, it's very enjoyable to see the live reload in action.

Under the hood, Nuxt's dev server is proxying every call to the Laravel's server, including the SPA rendering. Since `@nuxtjs/axios` module is included (and proxied, too), you can make API calls normally.

# Calling the API from the SPA

The SPA will surely need to call our API, so let's add a route to `routes/api.php` to retrieve the user information:

```php
<?php
Route::get('me', function () {
    // Let's return fake information.
    return [
        'name' => 'John Doe',
    ];
});
```

Now, edit `resources/nuxt/pages/index.vue`:

```html
<template>
  <h1>Hello {{ user.name }}!</h1>
</template>

<script>
export default {
    // https://github.com/nuxt-community/axios-module
    async asyncData({ app }) {
        const user = await app.$axios.$get('api/me');
        return { user };
    },
};
</script>
```

Voila! Your page should now look like this!

![api-call-picture](https://cdn.pbrd.co/images/H7v06bS.jpg)

> In order to keep the tutorial simple, we aren't using any kind of authentication here. Integrating Passport should be almost trivial here.

# Deployment

If you want to deploy your application, just run `npm run build`. The compiled assets will be placed in the `public/_nuxt` directory.

You can preview your final app with the well known artisan command `php artisan serve`.

> You may want to add the `.nuxt` and `public/_nuxt` directories to your `.gitignore`.

# Final thoughts

This is my first tutorial. I hope everything is clear and concise! Please, don't hesitate to ask questions here or create issues in the laravel-nuxt repositories. Thanks!