Llevo años construyendo SaaS con Laravel y he usado de todo: Blade clásico, SPAs con Vue Router + API REST, Livewire. Desde que adopté Inertia.js con Vue 3, mi velocidad de entrega se duplicó. No es exageración.
No necesitas una API separada. No necesitas Vue Router. No necesitas sincronizar tipos entre backend y frontend. El túnel de datos entre Laravel y Vue desaparece, y te quedas solo con lo que importa: construir features.
Cómo funciona el flujo de datos (y por qué importa)
En una SPA tradicional, cada pantalla requiere:
- Controlador Laravel → API Resource → JSON → Axios → Store Vue → Componente → Render.
En Inertia:
- Controlador Laravel →
Inertia::render()→ Componente Vue + props → Render.
El SSR (Server-Side Rendering) de Inertia hace que los motores de búsqueda vean HTML completo, y el usuario disfruta de navegación instantánea tipo SPA. Sin perder SEO, sin sacrificar UX.
// app/Http/Controllers/DashboardController.php
class DashboardController extends Controller
{
public function __invoke(): Response
{
$user = auth()->user();
return Inertia::render('Dashboard/Index', [
'stats' => [
'total_revenue' => (float) Revenue::totalForUser($user),
'active_subscriptions' => $user->subscriptions()->active()->count(),
'pending_invoices' => $user->invoices()->pending()->count(),
],
'recentActivity' => Activity::forUser($user)
->take(10)
->get()
->through(fn ($a) => [
'id' => $a->id,
'action' => $a->action,
'description' => $a->description,
'created_at' => $a->created_at->diffForHumans(),
]),
'filters' => request()->only(['period', 'status']),
]);
}
}
Sin Resources, sin transformaciones manuales en el frontend. Los datos llegan como props tipadas.
Lo que realmente acelera: patrones que funcionan
1. Formularios sin librería externa
No necesitas FormKit, VeeValidate ni Zod. Con @inertiajs/inertia y useForm:
<script setup>
import { useForm } from '@inertiajs/vue3';
const form = useForm({
name: '',
email: '',
plan: 'monthly',
terms: false,
});
function submit() {
form.post('/subscribe', {
preserveScroll: true,
onSuccess: () => form.reset(),
onError: (errors) => console.table(errors),
});
}
</script>
<template>
<form @submit.prevent="submit">
<TextInput v-model="form.name" :error="form.errors.name" />
<TextInput v-model="form.email" type="email" :error="form.errors.email" />
<PrimaryButton :disabled="form.processing">
{{ form.processing ? 'Processing...' : 'Subscribe' }}
</PrimaryButton>
</form>
</template>
form.processing evita doble envío. form.errors mapea automáticamente los errores de validación de Laravel. preserveScroll mantiene la posición al recargar.
2. Autorización sin duplicar lógica
// app/Http/Controllers/InvoicesController.php
class InvoicesController extends Controller
{
public function index(): Response
{
$this->authorize('viewAny', Invoice::class);
return Inertia::render('Invoices/Index', [
'invoices' => Invoice::forUser(auth()->user())
->with('items')
->latest()
->paginate(15)
->through(fn ($invoice) => [
'id' => $invoice->id,
'total' => $invoice->total_cents / 100,
'status' => $invoice->status,
'can' => [
'pay' => auth()->user()->can('pay', $invoice),
'download' => auth()->user()->can('download', $invoice),
'cancel' => auth()->user()->can('cancel', $invoice),
],
]),
]);
}
}
En el frontend, renderizas condicionalmente según can:
<button v-if="invoice.can.pay" @click="pay(invoice.id)">Pay Now</button>
Sin tener que replicar policies en JavaScript. Las reglas viven en Laravel, se consumen como props.
3. SSR real para SEO
Inertia SSR no es un “modo compatibilidad”. Es SSR nativo con Node:
npm install @inertiajs/server
node artisan inertia:start-ssr
Los crawlers reciben HTML completo con meta tags, títulos, descripciones y contenido. Tus páginas públicas (landing, docs, pricing) se indexan como cualquier web tradicional, mientras los usuarios logueados navegan con la fluidez de una SPA.
Testing: pest e inertia-testing
// tests/Feature/Http/Controllers/DashboardControllerTest.php
use Inertia\Testing\AssertableInertia;
test('dashboard shows correct stats for authenticated user', function () {
$user = User::factory()->create();
Subscription::factory()->for($user)->active()->create(['plan' => 'pro']);
$response = $this->actingAs($user)->get('/dashboard');
$response->assertInertia(fn (AssertableInertia $page) => $page
->component('Dashboard/Index')
->has('stats')
->where('stats.active_subscriptions', 1)
->has('recentActivity')
->where('filters', [])
);
});
test('dashboard redirects guests to login', function () {
$response = $this->get('/dashboard');
$response->assertRedirect('/login');
});
test('dashboard paginates recent activity', function () {
$user = User::factory()->create();
Activity::factory()->for($user)->count(25)->create();
$response = $this->actingAs($user)->get('/dashboard?page=2');
$response->assertInertia(fn (AssertableInertia $page) => $page
->component('Dashboard/Index')
->has('recentActivity.data', 10) // 10 per page
->where('recentActivity.current_page', 2)
);
});
Sin necesidad de mockear Axios, store de Vue ni llamadas API. El test habla directamente con la página renderizada y verifica las props.
Cuándo NO usar Inertia (con honestidad)
Inertia es mi opción por defecto, pero no es siempre la correcta:
- Equipos frontend y backend separados: si el frontend lo gestiona un equipo que no toca PHP, mejor una API tradicional con Vue Router.
- Offline-first / PWA agresivo: Inertia depende del servidor para navegar. Para apps que deben funcionar sin conexión, mejor SPA con SW.
- Múltiples clientes (web + mobile): si necesitas API para iOS/Android además de web, plantéate si merece mantener dos caminos o unificas en API.
- Tiempo real intensivo: WebSockets con Inertia funcionan, pero si tu app es 90% tiempo real (como un chat o dashboard tipo trading), una SPA con WS nativo da más control.
Para todo lo demás (SaaS, paneles de administración, herramientas internas, MVPs, landing con SSR), Inertia es imbatible.
Conclusión
Laravel + Inertia + Vue 3 no es una moda: es la forma más productiva que conozco de construir aplicaciones web completas sin duplicar lógica backend/frontend.
Si tu equipo usa Laravel y estás considerando cómo estructurar el frontend, mi recomendación es clara: prueba Inertia con un feature real (no un tutorial). Verás cómo desaparece la fricción entre backend y frontend.
¿Necesitas a alguien que ya domine este stack?
Llevo años construyendo SaaS completos con Laravel, Inertia y Vue 3, desde la base de datos hasta el deploy. Si tu equipo necesita un perfil senior que entregue rápido sin acumular deuda técnica:
- Stack: Laravel 11, PHP 8.3+, Vue 3 + TS + Inertia, Pest, Vite, Docker, GitHub Actions.
- Modalidad: EOR (Deel, Remote, Oyster), freelance B2B, o contrato directo en España.
- Disponibilidad: remoto España/UE/US, proyectos de 3+ meses o rol indefinido.
Ver mi perfil completo y condiciones →
Artículos relacionados
- Laravel + Vue para equipos distribuidos — Arquitectura Inertia, flujo async, onboarding
- Stack técnico para startups en 2026 — Laravel, Vue, Inertia, testing, despliegue
- Cómo uso Claude Code en producción con Laravel y Vue — Flujo matinal, refactor con IA
