Managing Global State with Inertia.js Shared Props
Stop manually passing user and session data to every controller. Learn how to use Inertia.js shared props to manage global state efficiently across your application.
27 Mar 2026, 07:24 UTC

The Problem: Prop Drilling and Redundant Fetching
When building a monolithic application with Inertia.js, you often encounter data that every single page needs. Think of the authenticated user's profile, a set of flash notifications, or the current application theme. Without a centralized way to handle this, you are forced to manually pass these variables from every single controller method to the Inertia render call.
This leads to "prop drilling"—passing data through layers just to reach a component—and repetitive server-side code that increases the surface area for bugs. The solution is Shared Props: a mechanism to define a global data set that Inertia automatically merges into every page response.
How Shared Props Work
Shared props are configured at the middleware level rather than the controller level. When a request hits your server, the Inertia middleware executes a specific method to gather global data. This data is then merged with the specific props returned by your controller before being sent as a JSON payload to the client.
On the frontend, these props are not passed as arguments to your page component. Instead, they are injected into the Inertia page object, making them accessible via a global helper (like usePage() in Vue or React) regardless of where the component sits in the hierarchy.
Implementation Example: Laravel Middleware
In a Laravel application, shared props are managed in the HandleInertiaRequests middleware. This is the single source of truth for global state.
// app/Http/Middleware/HandleInertiaRequests.php
public function share(Request $request):
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user(),
],
'flash' => [
'message' => $request->session()->get('message'),
],
'app_settings' => [
'theme' => config('app.theme'),
'locale' => app()->getLocale(),
],
]);
}
Accessing the Data on the Client
Because these props are shared, you don't need to add them to your return Inertia::render('Page', [...]) call. In a Vue 3 component, you access them like this:
<script setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const page = usePage()
const user = computed(() => page.props.auth.user)
const flashMessage = computed(() => page.props.flash.message)
</script>
<template>
<div v-if="flashMessage" class="alert">{{ flashMessage }}</div>
<p>Welcome, {{ user.name }}</p>
</template>
Critical Trade-offs and Limitations
While shared props simplify data delivery, they introduce specific architectural risks:
- Performance Overhead: The
sharemethod is executed on every single request. If you perform a heavy database query inside this method (e.g., fetching a complex permission tree), you will slow down every page load in your application. Keep shared props lightweight or use cached values. - Prop Collisions: If you define a shared prop named
userand your controller also returns a prop nameduser, the page-specific prop will override the shared one. This can lead to confusing bugs where global data suddenly disappears on specific pages. - State Synchronization: Shared props are sent during the initial page load or an Inertia visit. If the global state changes on the server (e.g., a user changes their theme in a settings modal), the shared props on other open components won't update until a new Inertia request is triggered or the page is reloaded.
Verifying the Implementation
To ensure your shared props are flowing correctly without guessing, use the browser's developer tools:
- Open the Network tab in your browser.
- Perform a navigation action (click a link) to trigger an Inertia request.
- Find the XHR request and inspect the JSON response body.
- Verify that the
propsobject contains both your page-specific data and the keys defined in your middleware.
If the shared props are missing, check that the HandleInertiaRequests middleware is correctly registered in your application's HTTP kernel.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.