Modern web development demands speed and coherence. When you build applications using a robust php web framework like Laravel alongside Vue, state management becomes central. Inertia.js bridges the gap between server-side routing and client-side rendering. With Inertia 3.x, handling data flow requires a clear strategy. You combine shared props, Pinia stores, and server-side rendering to create smooth experiences.
Let us dig into how these layers interact in a production environment.
Sharing Data: Laravel Props Meet Vue
Inertia eliminates the need for a separate REST API or GraphQL layer. Your Laravel controller returns a Vue component name along with an array of props.
public function show(User $user)
{
return Inertia::render('Users/Show', [
'user' => new UserResource($user),
]);
}
On the client side, Vue consumes these props directly. You access global data across components using Inertia’s usePage helper.
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const page = usePage()
const authUser = computed(() => page.props.auth.user)
This approach keeps your routing logic centralized in PHP. You gain the benefits of a modern frontend without maintaining client-side routers or duplicate state trees.
Persistent State: Pinia Stores and useRemember
Shared props handle server-state brilliantly. Client-only UI state, however, needs a dedicated store. Pinia provides lightweight, reactive stores for Vue 3 applications.
import { defineStore } from 'pinia'
export const useUIStore = defineStore('ui', {
state: () => ({
sidebarOpen: true,
activeTab: 'overview',
}),
})

Navigation in Inertia can cause component unmounting. When users navigate back and forth, local UI state resets by default. You solve this by integrating Inertia's useRemember hook inside your components or synchronizing state updates with Pinia.
import { useRemember } from '@inertiajs/vue3'
const form = useRemember({
searchQuery: '',
})
useRemember automatically preserves form inputs and scroll positions during history navigation. Pair this with your PHP developer tools and server configurations for predictable user journeys.
SSR Considerations: Hydrating Shared Data
Server-Side Rendering (SSR) improves initial load performance and search engine optimization. Running Inertia with SSR means your Laravel backend and Node.js SSR server must sync shared data on every request.
During an SSR request, Inertia evaluates your Vue components in a Node environment. Shared data: such as authentication states and flash notifications: must be injected into the initial page response.
import { createSSRApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
createInertiaApp({
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createSSRApp({ render: () => h(App, props) })
.use(plugin)
.use(createPinia())
.mount(el)
},
})

Ensure your Pinia stores initialize correctly on the server without accessing browser-only globals like window or localStorage. Guard your store initialization logic carefully.
Real-World Pattern: Auth, Flash, and UI
A standard application architecture divides state into three distinct buckets:
- Server state (passed via Inertia shared props).
- Global UI state (managed in Pinia).
- Transient flash notifications.
You configure shared props in Laravel's HandleInertiaRequests middleware.
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user() ? new UserResource($request->user()) : null,
],
'flash' => [
'success' => fn () => $request->session()->get('success'),
'error' => fn () => $request->session()->get('error'),
],
]);
}
Your Vue components read authentication and flash messages directly from usePage().props. When a user performs an action, Laravel returns a redirect with a flash message. Inertia picks up the new props automatically, updating the UI without manual store dispatches.
Polling and Caching: usePoll and useHttp
Real-time updates often require polling endpoints. Inertia 3.x and associated utilities support background data refreshing without full page reloads.
import { usePoll } from '@inertiajs/vue3'
usePoll(10000, { only: ['notifications'] })

When you need to build rest api with php for auxiliary async requests, combine Inertia requests with Pinia cache layers. Store fetched responses temporarily in your Pinia store to prevent redundant network calls during rapid tab switching.
Conclusion
Managing state in Laravel, Inertia 3.x, and Vue requires discipline. Let Laravel handle your database and routing logic. Use Inertia shared props for server data. Rely on Pinia for client-side UI states.
Explore the official Laravel documentation to deepen your setup. We would love to hear how your team structures state in modern monolithic architectures.