Laravel Daily's

Building Scalable SPAs with Laravel, Vue 3, and Inertia 3.x: A Complete Architecture Guide

hero image

Building modern single-page applications (SPAs) often involves a trade-off. You either choose the simplicity of a server-side monolith or the complexity of a decoupled frontend. Inertia.js bridges this gap. It allows you to build fully interactive SPAs using Laravel as your php web framework and Vue 3 as your frontend, without the overhead of a traditional API.

The release of Inertia 3.x introduces significant architectural improvements. These changes simplify data fetching, improve server-side rendering (SSR), and provide better tools for real-time interactivity. This guide covers how to structure your application to take full advantage of these new capabilities.

The Modern Monolith Architecture

The "Modern Monolith" approach treats your frontend and backend as a single unit. Laravel handles routing, authentication, and business logic. Vue 3 manages the user interface and state. Inertia acts as the glue.

Inertia 3.x moves away from Axios in favor of a built-in XHR client. This change gives the framework tighter control over request lifecycles. It enables features like native optimistic updates and more granular request cancellation. For a php developer, this means less time configuring HTTP interceptors and more time building features.

Core Stack Components

  • Laravel 11+: The foundation for your routing and data.
  • Vue 3: The reactive engine for your UI.
  • Inertia 3.x: The protocol connecting the two.
  • Pinia: The standard for client-side state management.
  • Vite: The build tool that powers the developer experience.

Non-Navigation Requests with useHttp

useHttp non-navigation requests

One of the most requested features in the Inertia ecosystem was a way to make requests without triggering a page visit. Previously, developers reached for Axios or native fetch for "background" tasks like liking a post or searching a list.

Inertia 3.x introduces the useHttp hook. It mirrors the ergonomics of useForm but is designed for requests that do not navigate.

Key Benefits of useHttp:

  • Integrated State: Access processing, errors, and progress directly.
  • Validation: Automatically maps Laravel's 422 validation responses to the local errors object.
  • Consistency: Uses the same underlying XHR client as the rest of your application.

When you build rest api with php endpoints to support these requests, return standard JSON. Inertia handles the rest. This keeps your background tasks feeling like a native part of the framework rather than a separate implementation.

Keeping Data Fresh with usePoll

Real-time polling and data freshness

Not every application requires the complexity of WebSockets via Reverb or Pusher. For many dashboards, periodic updates are sufficient.

Inertia 3.x simplifies this with the usePoll helper. This tool allows you to refresh page data on a set interval. It is specifically designed to work with partial reloads.

import { usePoll } from '@inertiajs/vue3'

usePoll(5000, {
    only: ['stats', 'notifications'],
    onStart: () => console.log('Polling started'),
})

By using the only key, you ensure that only specific pieces of data are fetched from the server. This reduces server load and keeps the payload small. It is a pragmatic way to achieve a "real-time" feel without managing a WebSocket server.

Smooth Data Loading: Deferred Props and Slots

User experience often suffers when a page waits for slow database queries before rendering. Inertia's Deferred props solve this by allowing the initial page to load immediately while slow data fetches in the background.

In version 3.x, the <Deferred> component receives a significant upgrade: the reloading slot.

Improved Reloading Logic

In previous versions, a partial reload would often reset a component to its loading state. This caused flickering. Now, existing data remains visible during a refresh. You can use the reloading slot prop to show a subtle indicator: like a spinner or a progress bar: while the user continues to interact with the current data.

This approach is perfect for search results or paginated lists. It keeps the UI stable and responsive.

State Management with Pinia

While Inertia manages your page props, you still need a place for "global" client-side state. Pinia is the recommended choice for Vue 3.

When to use Pinia vs. Inertia Props:

  • Inertia Props: Data that comes from the database (users, posts, settings).
  • Pinia: UI-only state (sidebar toggle, temporary cart items, local filters).

Avoid duplicating data. If a piece of state is returned from a Laravel controller, let Inertia manage it. If it is ephemeral and only exists in the browser, put it in a Pinia store.

SSR and Performance with Vite

Server-Side Rendering (SSR) used to be a point of friction for Inertia developers. You needed a separate Node.js process running alongside your PHP server.

The new @inertiajs/vite plugin changes this. During development, the SSR server now runs in-process with Vite. This means zero configuration for php developer tools. When you run npm run dev, SSR "just works."

In production, Laravel's new Blade components like <x-inertia::head> solve long-standing issues with duplicate title tags. These components are SSR-aware and allow you to define fallback content easily.

Architecture Patterns for Scalability

To keep a large Inertia application maintainable, follow these patterns:

1. Dedicated Data Transfer Objects (DTOs)

Don't pass Eloquent models directly to your frontend. Use Spatie’s Data Mapper or simple Laravel Resources. This prevents leaking sensitive data and provides a clear contract for your Vue components.

2. Action Classes

Move business logic out of controllers and into Action classes. This makes your code testable and reusable across your web routes and API endpoints.

3. Folder by Feature

Instead of a giant Pages folder, group your Vue components by feature. For example, Resources/js/Features/Billing could contain the pages, components, and Pinia stores related to payments.

Deployment and Monitoring

Laravel Cloud and Managed Infrastructure

Building a scalable architecture is only half the battle. You need an infrastructure that can handle the load.

Laravel Cloud provides a managed environment specifically tuned for these types of applications. It handles the scaling, object storage, and monitoring automatically. For teams that prefer managing their own servers, Laravel Forge remains the gold standard for deploying Laravel-based SPAs.

Final Thoughts

Inertia 3.x transforms the Vue and Laravel experience from a simple connection into a deeply integrated ecosystem. By leveraging useHttp for background tasks, usePoll for fresh data, and the improved SSR workflow, you can build applications that feel as fast as a custom-built SPA with a fraction of the complexity.

The modern monolith isn't just a trend. It is a more efficient way to ship high-quality software. We'd love to hear how you're using these new features in your latest projects.


Previous
Supercharge Your Workflow: How Laravel Boost Turns AI Agents into Laravel Experts
Next
Laravel Trends 2026: What's Shaping the PHP Framework Landscape