Getting started with Inertia.js
What is Inertia.js
Inertia is a new approach to building classic server-driven web apps. Inertia allows you to create fully client-side rendered, single-page apps, without much of the complexity. And inertia has no client side routing, does not require an API also.
If we say simply, you create controllers, get the data from the database and render views.
Installation
Server-side setup
Install server-side adapter using composer
composer require inertiajs/inertia-laravel
Setup the root template
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link href="{{ mix('/css/app.css') }}" rel="stylesheet" />
<script src="{{ mix('/js/app.js') }}" defer></script>
</head>
<body>
@inertia
</body>
</html>
@inertia directive is a helper that creates a root <div> with an id of app that contains the page information and it tells Laravel that the views are generated using Inertia.
Client-side setup
setup the client-side adapter using these commands:
npm install @inertiajs/inertia @inertiajs/inertia-vue
or
yarn add @inertiajs/inertia @inertiajs/inertia-vue
update the resources/js/app.js
import { InertiaApp } from '@inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp)
const app = document.getElementById('app')
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => require(`./Pages/${name}`).default,
},
}),
}).$mount(app)
Define the routes
For example:
I am going to discuss index view of users form and we can define the following route in web.php
Route::get('/users','\App\Http\Controllers\UsersController@index');
Create a controller
class UsersController extends Controller
{
public function index(Request $request): \Inertia\Response
{
$users = User::when($request->get('search') ?? '', function ($query, $search) {
$query->where('full_name', 'like', "%{$search}%");
})
->orderBy('id', 'ASC')
->paginate('10')
->only('id', 'full_name', 'email', 'phone', 'country', 'investor_type');
return Inertia::render('Users/Index', ['users' => $users]);
}
}
We can create a controller using php artisan:make controller UsersController
And render function is used for making inertia response. This function uses components and data.
Create a page(view) of index
After creating UsersController
, we can create the index component under resources/js/Pages/Users
. Assume the filename to be Index.vue
, following code shows the contents of Index.vue
<template>
<layout>
<div class="container">
<div class="col-6">
<form @submit.prevent="search">
<div class="input-group mb-3">
<input type="text" v-model="q" class="form-control" placeholder="Search...">
<button class="btn btn-outline-secondary" type="submit" id="button-addon2">Search</button>
</div>
</form>
</div>
<table class="table table-striped">
<thead>
<tr class="bg-gray-100">
<th scope="col">Id</th>
<th scope="col">Full Name</th>
<th scope="col">Email</th>
<th scope="col">Phone</th>
<th scope="col">Country</th>
<th scope="col">Investor Type</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users.data" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.full_name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.phone }}</td>
<td>{{ user.country }}</td>
<td>{{ user.investor_type }}</td>
</tr>
</tbody>
</table>
<pagination :links="users.links" />
</div>
</layout>
</template>
<script>
import Layout from "../../Shared/Layout";
import Pagination from "../../Shared/Pagination";
export default {
components: { Layout,Pagination},
props: {
users: Object,
},
data() {
return {
q: '',
form: {
full_name: null,
email: null,
phone: null,
country: null,
investor_type: null,
},
}
},
mounted() {
console.group('Users');
console.log(this.users.links);
console.log(this.users.data);
console.groupEnd();
},
methods: {
search() {
this.$inertia.get(`/users?search=${this.q}`)
}
}
}
</script>
Create the layouts of page
In this example, I use Layout component that comes from resources/js/Shared/Layout.vue
<template>
<main>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Users
</h2>
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<button class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="hidden md:block">
<div class="ml-10 flex items-baseline space-x-4">
<inertia-link href="/users"
class="bg-black-900 text-black-50 px-3 py-2 rounded-md text-sm font-medium">Users
</inertia-link>
</div>
</div>
</nav>
<article>
<slot/>
</article>
</main>
</template>
<script>
export default {
inject: ['page'],
}
</script>
That's all we have to do to create simple index view of users using inertia.js. If you want more information about inertia.js please refer the official documentation: