DEV Community

Cover image for Laravel Jetstream: From blade to using Inertia & Vue
Brian Dillingham
Brian Dillingham

Posted on • Edited on

Laravel Jetstream: From blade to using Inertia & Vue

Laravel Jetstream + Inertia is an amazing foundation for building modern apps using Vue (auth, basic ui kit) without the struggles of SPA. This article assumes you followed the installation steps on Laravel Jetstream's website for Inertia and you are ready to jump in but you're a little new to Inertia or Vue.

How do I work with Inertia?

Inertia may seem very different at first, but nothing actually changes with how you think about things like routes, controllers and views within Laravel. You still add a route to web.php, point it to a controller and return a view.

The main difference is that you return Inertia::render() from a controller. This response will ultimately render a Vue component and pass it data defined in our Laravel controllers.. solving a complexity of using Vue + Laravel.

Route::get('posts', 'PostsController@index')->name('posts.index');
Enter fullscreen mode Exit fullscreen mode
public function index()
{
    $posts = Post::all();

    return Inertia::render('Posts/Index', [
        'posts' => $posts
    ]);
}
Enter fullscreen mode Exit fullscreen mode

Where do I put views?

There is a resources/js/Pages folder created when you installed Jetstream. Add Posts/Index.vue within that folder to handle Inertia::render('Posts/Index'). Similar to view('posts.index')

Where are my changes when I refresh?

Since we are using Vue, we need to compile our vue components / pages or the changes we make in .vue files will not show in the browser. It basically just means npm install to install dependencies and npm run watch to watch files for changes and re-compile. Luckily Laravel makes this user friendly. docs

How do I access the view data?

The vue component will automatically receive the data we added to Inertia::render() within our controller just like when we say view()->with(). The key differences are we need to add each variable as a property in props so vue is aware and use vue's template syntax instead of Blade.

resources/js/Pages/Posts/Index.vue
Enter fullscreen mode Exit fullscreen mode
<template>
    <app-layout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Posts
            </h2>
        </template>

        <div>
            <div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
                <div v-for="post in posts" :key="post.id">
                    {{ post.title }}
                </div>
            </div>
        </div>
    </app-layout>
</template>

<script>
import AppLayout from '@/Layouts/AppLayout'

export default {
    props: ['posts'],

    components: {
        AppLayout
    },
}
</script>
Enter fullscreen mode Exit fullscreen mode

What is <app-layout>?

Jetstream comes with a lot of really useful vue components for things like form elements and modals, located in resources/js/Jetstream, but <app-layout> is in resources/js/Layouts and is the main shell that renders this: Laravel Jetstream Vue Inertia

Adding your content within this vue component means you'll automatically have navigation in place and a nice starting point for your layout.

How do I link to my page?

Jetstream installs Ziggy to handle using named routes within Inertia / Vue. Using Ziggy's route method & the <inertia-link> component:

<inertia-link :href="route('posts.index')">
    Posts
</inertia-link>
Enter fullscreen mode Exit fullscreen mode

To add a link to the main navigation within the <app-layout>, open the layout file within resources/js/Layouts/App.vue and add a link:

<!-- Navigation Links -->
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
    <jet-nav-link :href="route('dashboard')" :active="route().current('dashboard')">
        Dashboard
    </jet-nav-link>

    <jet-nav-link :href="route('posts.index')" :active="route().current('posts.index')">
        Posts
    </jet-nav-link>
</div>
Enter fullscreen mode Exit fullscreen mode

(<jet-nav-link> is a component in resources/js/Jetstream)

How do I submit forms?

Inertia provides a really helpful way of using ajax to submit forms. First, use v-model to connect your inputs to the vue state defined in the data() section of your vue component and call a method using the @submit event handler.

<template>
  <form @submit.prevent="submit">
    <label for="title">Title:</label>
    <input id="title" v-model="form.title" />
    <label for="body">Body:</label>
    <input id="body" v-model="form.body" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        title: null,
        body: null
      },
    }
  },
  methods: {
    submit() {
      this.$inertia.post('/posts', this.form)
    },
  },
}
</script>
Enter fullscreen mode Exit fullscreen mode

How does Inertia render Vue?

Laravel Jetstream sets the root view to app.blade.php in app/Http/Middleware/HandleInertiaRequests which is rendering:

<body class="font-sans antialiased">
   @inertia
</body>
Enter fullscreen mode Exit fullscreen mode

Which is outputting the root div Vue will attach to and passing it data:

<div id="app" data-page="{{ json_encode($page) }}"></div>
Enter fullscreen mode Exit fullscreen mode

How is resources/js/Pages defined?

This mapping happens in resources/app.js

resolveComponent: (name) => require(`./Pages/${name}`).default,
Enter fullscreen mode Exit fullscreen mode

Conclusion

Hope you found that helpful. I plan to write more about Jetstream as I find it to be extremely powerful. If you have feedback, I'd love to hear it on twitter.

https://twitter.com/dillingham_dev

Top comments (4)

Collapse
 
jenueldev profile image
Jenuel Oras Ganawed

can I install other component libraries to use in my view? like for example vue bootstrap?

Collapse
 
jenueldev profile image
Jenuel Oras Ganawed

how do I view a blade without using Inertia

Collapse
 
carleo98_o profile image
carlos oblitas

Es recomendado cambiar la plantilla frontent de Jetstream por una en particular?, o de manera forzada debemos de utilizar la por default?

Collapse
 
tanzimibthesam profile image
Tanzim Ibthesam

I want to ask can I use packages like Spatie role Faker with Inertia