Tutorial de Inertia.js con Laravel

 

Índice

  1. Introducción a Inertia.js

  2. ¿Cómo funciona Inertia.js?

  3. Instalación y configuración

  4. Estructura del proyecto

  5. Enrutamiento en Inertia

  6. Prácticas y ejemplos


1. Introducción a Inertia.js

¿Qué es Inertia.js?

Inertia.js es una capa de comunicación entre el lado del cliente y el servidor que permite crear aplicaciones de una sola página (SPA - Single Page Application) sin la complejidad de construir una API REST.

Características principales:

  • ✅ No es un framework, es una capa de comunicación

  • ✅ Permite crear aplicaciones SPA de forma eficiente

  • ✅ Elimina la necesidad de construir APIs REST

  • ✅ Compatible con Vue.js, React y Svelte

  • ✅ Se integra con Laravel, Django y Ruby on Rails

Ventajas sobre el enfoque tradicional

Enfoque tradicionalCon Inertia.js
Crear API RESTNo se necesita API
Repetir lógica en cliente y servidorLógica única en el servidor
Múltiples capas de comunicaciónComunicación directa
Cliente y servidor separadosIntegración natural

2. ¿Cómo funciona Inertia.js?

Concepto fundamental

Inertia.js actúa como un puente entre:

  • El servidor (Laravel, Django, etc.)

  • El cliente (Vue.js, React, Svelte)

text
┌─────────────┐      Inertia.js      ┌─────────────┐
│  Servidor   │ ◄──────────────────► │   Cliente   │
│  (Laravel)  │                       │   (Vue.js)  │
└─────────────┘                       └─────────────┘

Flujo de trabajo

  1. El usuario navega a una URL

  2. Laravel procesa la ruta y devuelve un componente Vue

  3. Inertia.js intercepta la respuesta y renderiza el componente

  4. El contenido cambia sin recargar la página

Mapeo de rutas

La característica clave es el mapeo directo entre rutas de Laravel y componentes de Vue:

php
// routes/web.php
Route::get('/dashboard', function () {
    return Inertia::render('Dashboard');
});

Este mapeo traduce automáticamente a:

javascript
// Vue component
<template>
    <div>Dashboard</div>
</template>

3. Instalación y configuración

Requisitos previos

  • PHP 8.0+

  • Composer

  • Node.js y NPM

  • Base de datos (MySQL, PostgreSQL, etc.)

Paso 1: Crear el proyecto Laravel

bash
# Crear proyecto con Laravel Breeze (incluye Inertia)
composer create-project laravel/laravel proyecto-inertia

# O con el instalador de Laravel
laravel new proyecto-inertia

Paso 2: Instalar Breeze con Inertia

bash
# Navegar al proyecto
cd proyecto-inertia

# Instalar Breeze con Inertia
composer require laravel/breeze --dev

# Ejecutar el comando de instalación
php artisan breeze:install

Seleccionar opciones:

  • Cuando pregunte Which stack do you want to use? → seleccionar inertia

  • Would you like to use dark mode? → seleccionar según preferencia

Paso 3: Instalar dependencias del frontend

bash
# Instalar paquetes Node.js
npm install

# Compilar assets para desarrollo
npm run dev

# O para producción
npm run build

Paso 4: Configurar la base de datos

env
# .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nombre_base_datos
DB_USERNAME=usuario
DB_PASSWORD=contraseña

Paso 5: Ejecutar migraciones

bash
php artisan migrate

4. Estructura del proyecto

Estructura principal

text
proyecto-inertia/
├── app/
│   └── Http/
│       └── Controllers/
├── database/
│   └── migrations/
├── resources/
│   ├── js/
│   │   ├── Components/      # Componentes Vue reutilizables
│   │   ├── Pages/           # Páginas de la aplicación
│   │   ├── Layouts/         # Layouts principales
│   │   └── app.js           # Punto de entrada
│   └── views/
│       └── app.blade.php    # Única vista Blade
├── routes/
│   └── web.php              # Rutas con Inertia
└── package.json

Archivo principal (app.blade.php)

php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    @vite('resources/js/app.js')
    @inertiaHead
</head>
<body>
    @inertia
</body>
</html>

Punto de entrada (app.js)

javascript
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'

createInertiaApp({
    resolve: (name) => resolvePageComponent(
        `./Pages/${name}.vue`,
        import.meta.glob('./Pages/**/*.vue')
    ),
    setup({ el, App, props, plugin }) {
        createApp({ render: () => h(App, props) })
            .use(plugin)
            .mount(el)
    },
})

5. Enrutamiento en Inertia

Enrutamiento básico

En Laravel (routes/web.php):

php
use Inertia\Inertia;

// Ruta simple
Route::get('/', function () {
    return Inertia::render('Welcome');
});

// Ruta con parámetros
Route::get('/user/{id}', function ($id) {
    return Inertia::render('User/Profile', [
        'user' => User::find($id)
    ]);
});

En Vue (resources/js/Pages/Welcome.vue):

vue
<template>
    <div>
        <h1>Bienvenido</h1>
        <p>Esta es la página de inicio</p>
    </div>
</template>

<script>
export default {
    name: 'Welcome'
}
</script>

Pasar datos del servidor al cliente

php
// En Laravel
Route::get('/dashboard', function () {
    return Inertia::render('Dashboard', [
        'user' => auth()->user(),
        'stats' => [
            'posts' => Post::count(),
            'comments' => Comment::count()
        ]
    ]);
});
vue
<!-- En Vue -->
<template>
    <div>
        <h1>Bienvenido, {{ user.name }}</h1>
        <p>Posts: {{ stats.posts }}</p>
        <p>Comentarios: {{ stats.comments }}</p>
    </div>
</template>

<script>
export default {
    props: ['user', 'stats']
}
</script>

Navegación entre páginas

vue
<template>
    <div>
        <!-- Link a otra página -->
        <Link href="/about">Acerca de</Link>
        
        <!-- Link con parámetros -->
        <Link href="/user/1">Usuario 1</Link>
    </div>
</template>

<script>
import { Link } from '@inertiajs/vue3'

export default {
    components: { Link }
}
</script>

6. Prácticas y ejemplos

Ejemplo 1: Crear un panel de control simple

Paso 1: Crear la ruta

php
// routes/web.php
Route::get('/dashboard', function () {
    return Inertia::render('Dashboard', [
        'user' => auth()->user()
    ]);
})->middleware(['auth'])->name('dashboard');

Paso 2: Crear el componente

vue
<!-- resources/js/Pages/Dashboard.vue -->
<template>
    <Layout>
        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 text-gray-900">
                        <h2>Dashboard</h2>
                        <p>Bienvenido, {{ user.name }}</p>
                    </div>
                </div>
            </div>
        </div>
    </Layout>
</template>

<script>
import Layout from '@/Layouts/AppLayout.vue'

export default {
    components: { Layout },
    props: ['user']
}
</script>

Ejemplo 2: Formulario con envío de datos

Paso 1: Crear el controlador

php
// app/Http/Controllers/PostController.php
use Illuminate\Http\Request;
use Inertia\Inertia;

public function create()
{
    return Inertia::render('Posts/Create');
}

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|max:255',
        'content' => 'required'
    ]);

    Post::create($request->all());

    return redirect()->route('dashboard')
        ->with('success', 'Post creado exitosamente');
}

Paso 2: Crear la vista del formulario

vue
<!-- resources/js/Pages/Posts/Create.vue -->
<template>
    <Layout>
        <div class="max-w-2xl mx-auto p-6">
            <form @submit.prevent="submit">
                <div class="mb-4">
                    <label>Título</label>
                    <input v-model="form.title" 
                           type="text" 
                           class="w-full border rounded p-2">
                    <div v-if="errors.title" class="text-red-500">
                        {{ errors.title }}
                    </div>
                </div>

                <div class="mb-4">
                    <label>Contenido</label>
                    <textarea v-model="form.content" 
                              class="w-full border rounded p-2"></textarea>
                    <div v-if="errors.content" class="text-red-500">
                        {{ errors.content }}
                    </div>
                </div>

                <button type="submit" 
                        class="bg-blue-500 text-white px-4 py-2 rounded">
                    Guardar
                </button>
            </form>
        </div>
    </Layout>
</template>

<script>
import Layout from '@/Layouts/AppLayout.vue'
import { useForm } from '@inertiajs/vue3'

export default {
    components: { Layout },
    setup() {
        const form = useForm({
            title: '',
            content: ''
        })

        function submit() {
            form.post('/posts')
        }

        return { form, submit }
    }
}
</script>

Ejemplo 3: Tabla con paginación

php
// En Laravel
Route::get('/users', function () {
    return Inertia::render('Users/Index', [
        'users' => User::paginate(10)
    ]);
});
vue
<!-- En Vue -->
<template>
    <div>
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Nombre</th>
                    <th>Email</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="user in users.data" :key="user.id">
                    <td>{{ user.id }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.email }}</td>
                </tr>
            </tbody>
        </table>
        
        <!-- Paginación automática -->
        <Pagination :links="users.links" />
    </div>
</template>

<script>
import Pagination from '@/Components/Pagination.vue'

export default {
    components: { Pagination },
    props: ['users']
}
</script>

7. Resumen y consejos clave

Lo que debes recordar

  1. Inertia.js no es un framework - Es una capa de comunicación

  2. No necesitas API REST - La comunicación es directa

  3. Mapeo de rutas - Las rutas de Laravel se traducen a componentes Vue

  4. Código DRY - No repitas lógica en cliente y servidor

  5. Estado compartido - Los datos fluyen naturalmente

Diferencias con Laravel Livewire

CaracterísticaInertia.jsLivewire
TecnologíaVue/React/SveltePHP puro
Curva de aprendizajeMediaBaja
RendimientoExcelenteBueno
EcosistemaFrontend modernoPHP nativo

Próximos pasos

✅ Explora los componentes de @inertiajs/vue3:

  • Link - Navegación

  • useForm - Manejo de formularios

  • usePage - Acceso a datos de página

  • Head - Metadatos HTML

✅ Profundiza en:

  • Middleware de autenticación

  • Manejadores de errores

  • Progreso de carga

  • Sesiones y flash messages


Recursos útiles


Ejercicio práctico

Crea una pequeña aplicación de tareas:

  1. Página principal con lista de tareas

  2. Formulario para agregar nuevas tareas

  3. Posibilidad de marcar tareas como completadas

  4. Eliminar tareas

Requisitos:

  • Usa Inertia.js con Laravel

  • Base de datos para almacenar tareas

  • Componentes Vue reutilizables

¡Ya estás listo para empezar a construir aplicaciones con Inertia.js y Laravel!

Comentarios

Entradas más populares de este blog

Tareas con Laravel + Inertia + Jetstream

HACER CAMBIOS-A TU EJEMPLO

HACER CAMBIOS-AL EJEMPLO POR DEFECTO