In this tutorial we'll use Laravel as an API and Nuxt 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 and laravel-nuxt-js.
There are more reasons to use these packages, such as when using Laravel 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:
composer create-project laravel/laravel spa
Go inside the spa
directory with your terminal.
Install laravel-nuxt (for PHP)
# 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
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
// 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:
{
"private": true,
"scripts": {
"start": "laravel-nuxt dev",
"build": "laravel-nuxt build"
},
"dependencies": {
"laravel-nuxt": "^1.0.0"
}
}
Install the dependencies:
npm install
The laravel-nuxt
package will install Nuxt for you, along with Vue, vue-router, @nuxtjs/axios, etc. Let's create the nuxt.config.js
file:
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
:
<template>
<h1>Hello {{ name }}!</h1>
</template>
<script>
export default {
data: () => {
return { name: 'world' };
},
};
</script>
Finally, run:
npm start
Go to http://localhost:8000. You should see this:
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
Route::get('me', function () {
// Let's return fake information.
return [
'name' => 'John Doe',
];
});
Now, edit resources/nuxt/pages/index.vue
:
<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!
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
andpublic/_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!
Oldest comments (55)
That's an impressive piece of work, a full Laravel/Nuxt integration! How did you get all of this 'magic' working? I'm planning to read your source code to understand how it works under the hood.
Searching for "laravel" and "nuxt" I saw that there were only a few Github projects dealing with this, that's a bit surprising since Laravel has a heavy 'bias' towards Vue.js and SSR (and hence Nuxt.js) seems a good fit for many Laravel projects (especially content-focused apps/websites).
I saw one other Laravel/Nuxt starter repo, but yours seems a bit more clean and lightweight.
Definitely want to try this out (another option would be to go for a pure Javascript approach, using node/express for the API/backend/server part rather than PHP/Laravel).
However the ease of development and the vibrant community are what attract me to a Laravel based solution (compared to for instance Django).
Thanks! I think you'll an easy time reading from the source: there isn't much code and part of it is documented using docblocks.
I also searched for a Laravel&Nuxt integration, but found none that fit my tastes. I expect your feedback on it soon! :)
The ease of development and the code quality is what attracts me to using Laravel as an API too. There are a few things I'd change from Laravel, but I still love it!
I'll create another tutorial about authorization using LaravelNuxt in the next weeks... maybe you'll be interested.
Great job ... what surprised me is that while Laravel "ships" with Vue.js you can hardly find anything about integrating Laravel with Nuxt, even though the two seem a natural combo. Your repo seems to be one of the very few solutions!
What I understood is that in fact you need Javascript on the server (node/express) to support SSR. So what you did (if I understood correctly) is run a separate node/express server and proxy requests between the node server and the Laravel server, right? And then you just code your app in Laravel (the API part) and Vue (the client part), no need to worry about the node/express part.
Sounds pretty nifty, I'll read your source code to understand the details.
Yes I would definitely be interested in your authorization tutorial with LaravelNuxt!
I can't get it! the api/me should have been requested from the server and pre-rendered before reaching the client side, am I right?
I can see the request in the network inspection, that should make no difference between acyncData and normal data?
please clarify this for me, thanks :).
Hi! There's no prerendering when using laravel-nuxt. The api/me request is sent from client side when activating the JS route.
You should use async data if you need your page to wait to be rendered until the data is fetched.
Really good app. But it is also possible to create Laravel single page app without using vue-router, but that would mean using Laravel for backend rendering. This may not be that efficient but it is easier to do.
It fails at
npm start
command:@ start /Users/mathewparet/eclipse/workspace/getitdone
laravel-nuxt dev
/Users/mathewparet/eclipse/workspace/getitdone/node_modules/laravel-nuxt/bin/laravel-nuxt-dev.js:52
...process.env,
^
SyntaxError: Unexpected token ...
at createScript (vm.js:74:10)
at Object.runInThisContext (vm.js:116:10)
at Module._compile (module.js:533:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ start: laravel-nuxt dev
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/mathewparet/.npm/_logs/2018-04-01T14_39_48_780Z-debug.log
gMac:getitdone mathewparet$
Hi there. You need to upgrade your node version: v8 and v9 are tested, but not sure if v6 works.
Hello Cristian I have a question, when I see the source code of my view, I don't see the rendered text of Hello Eduardo, why? help me please.
thepracticaldev.s3.amazonaws.com/i...
Hello Eduardo. What you're seeing is the generic page that Nuxt provides to you (it's always the same because there's no server side rendering). When the JS is loaded, the Vue Router will render the correct HTML (depending on the actual URL).
Hello Cristian. But the major feature to use nuxt is server side rendering from my point of view. How can I achieve that with laravel-nuxt and laravel-nuxt-js?
This is not at the scope as for now. If you want to use SSR you'll need to solve some problems like starting node from within PHP and passing some data. laravel-nuxt offers a simple and easy solution to get started, but without SSR.
What's the point of using Nuxtjs if not for ssr?
You can still benefit from:
vue routing is not working as in nuxt working . how can i config vue routing .. ? looking for solution thanks.
Nice and clean !, <3 Thanks !
I have a question (I do not know if I understood correctly) or will it work on a production server without noda? I am a beginner so I ask, and I would love to use NUXT in my application
You don't need node in production, only in development. You must include your compiled assets in the deployment process.
Thank you :-)
Can Laravel Mix still be used as part of the build process? I’m using Tailwind for utility-based CSS approach & would like to utilize their PurgeCSS setup as part of it. Mix makes that in incredibly elegant solution. Thanks!
This is tightly coupled to nuxt... I don't think they can be merged, but you can still setup PurgeCSS and use Tailwind!
How can I use valet to run my app?
( somehow okay, I just used "npm run build")
but How can I use valet while constantly editing my *.vue files?
I'm not sure how Laravel Valet works, but the laravel-nuxt package assumes you have php installed.
that was so helpful , thank you
I have problem with static resouces images, not found 404 after npm run build.
Hi there! Are the images in the public/_nuxt directory after building? If not, do you use the resources/nuxt/static directory to publish images?
You could also try to import the images in your components (you'll receive the URL string) and use it in the views.
Hi Cristian. What about the files that are stored in the Laravel storage folder? I am not able to access them. Should I try another approach or I am on the right path?
UPDATE: I have created a symlink for storage/ inside static folder. Everyhting is working as expected.
Hello, Cristian. On
npm run build
i can't access the files from static directory. There is something extra I need to do in order to access them? Thank you!Hi, @jintoples . How did you managed to fix this error? My files can be accessed when I run
npm run start
but when I runnpm run build
the files are not available anymore.That's impressive. I got a chance to learn. Thanks
php artisan serve --host=domain --port=8000 not working
Great tutorial Cristian. I have already implemented a login system using JWT authentication and @nuxtjs/auth.
Hi, Cristian!
Do you have any idea why baseURL it is recognized only when using "npm run build" and "php artisan serve" commands? When I run "npm run start" the baseURL it is not using the provided value
axios: {
baseURL: development ? 'devsite/api' : "livesite/api"
},
Found a solution: browserbaseURL should be provided also.
axios: {
baseURL: development ? 'devsite/api' : "livesite/api",
browserBaseURL: development ? 'devsite/api' : "livesite/api"
},
Oh, great!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.