Features of a Laravel Inertia project
If we review the HTTP handlers, we're all set for authentication. There's not much mystery; it's very similar to what we had, for example, with Breeze (which, by the way, has since been phased out).
This is what we have: a bit of logic and Inertia components for rendering views. We'll explain this a bit later, but for now, let's just give a general overview.
Rendered with Inertia
Spoiler alert: Inertia is used to render components in Vue (or React, if you choose). In this case, we're using Vue. This is the core of Inertia: simply rendering components instead of using Blade files.
The same thing happens with all the views we render, as you can see by inspecting the controllers. The names are quite descriptive and reflect the operation they perform. Basically, we have a complete authentication module: login, registration, password recovery, etc. Nothing fancy.
Controller-controlled views
An important thing is that, in Inertia, views are rendered using controllers, not directly using components as you might do in “pure” Laravel (or Blade). If you want to render something, by default you do it using controllers, as we're doing here.
Middleware and global messages
This file is also important because it acts as middleware, that is, an intermediary. We use it when we want to pass something to the components. Later, we'll use it to send Flash messages, which are temporary messages that are displayed after performing an action (for example, successfully saving a form).
This is where we configure the data we want to send globally to all views.
User model and authentication
The user model is completely basic, with the Authenticatable, HasFactory, Notifiable, and a few other traits. There's also a Provider, which seems borrowed, but there's not much more mystery here.
Where are the views?
If we check the resources/views folder, you'll see that there's only one view. We'll pause here to explain this: I already told you we use controllers and render Vue components. So, where are the other views?
Answer: I already told you... they're components in Vue!
We only have one Blade view, but there are many views rendered through Vue components.
For every page you see, there's a component behind it. And they're organized like this:
Pages: Contains the complete pages.
Components: Contains the reusable pieces that make up those pages.
The structure is fairly well modularized.
Layouts and application structure
We also have the Layouts folder, which contains common page structures.
If we open the bootstrap file (app.ts or app.js), we'll see how the application is initialized.
We also have App.blade.php, which is the only Blade file, and we're importing it as the main template. Inertia already tracks it automatically, so you don't need to move or rename it.
Initializing the app with Inertia
Starting the app is similar to any Vue project:
We use createApp, although it's customized here.
We specify the path to our pages.
We define where the components will be mounted.
We configure custom plugins (such as the navigation progress bar):
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./pages/${name}.vue`, import.meta.glob<DefineComponent>('./pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(Oruga)
.use(CkeditorPlugin)
.use(ZiggyVue)
.mount(el);
All this happens in the boot file.
Location and use of components
As we've seen, pages are in the Pages folder, and reusable elements are in Components. You can see everything being used and can also reuse them yourself.
Form management with Inertia
An important difference from a traditional Vue application is data handling. We don't use Axios directly here. Instead, we use an internal Inertia mechanism called useForm.
We import this useForm and use it directly to handle forms and data in a cleaner way. Here we define the form data, submission, and any other related logic.