Sharing Global Page Data in InertiaJS with Laravel
Configure InertiaJS shared data once in Laravel middleware and read it client-side with usePage().props.shared. Avoid secrets, heavy models, and client mutations.
02 Sept 2025, 13:00 UTC

Shared data removes repeated controller props
In an InertiaJS Laravel application, each controller visit returns a JSON page object. When several pages need the same information—such as the signed-in user, flash messages, or feature flags—you would otherwise pass those props from every controller method. Inertia shared data lets you declare those values once in middleware so they are merged into every Inertia response automatically.
HTTP middleware is a Laravel layer that inspects or modifies requests and responses. A closure is an anonymous function that can capture values from its surrounding scope.
Useful takeaway: configure shared data in app/Http/Middleware/HandleInertiaRequests.php, then read it on the client with usePage().props.shared. Treat shared data as small, serializable, and request-scoped.
Worked configuration: Laravel middleware
Assumes Laravel 10 or 11 with the Inertia Laravel adapter and a React or Vue 3 frontend. Open app/Http/Middleware/HandleInertiaRequests.php. The share method returns an array. Values can be closures, so they are evaluated per request when Inertia builds the response.
<?php
namespace App\Http\Middleware;
use Inertia\Inertia;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class HandleInertiaRequests extends Middleware
{
protected $rootView = 'app';
public function version(Request $request): ?string
{
return parent::version($request);
}
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth.user' => fn () => $request->user(),
'flash' => fn () => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
'appName' => config('app.name'),
]);
}
}
Save the file with normal application filesystem permissions. No artisan command is required to activate it because Laravel automatically discovers HTTP middleware. The auth.user closure runs on every Inertia request and returns the current authenticated user or null.
Reading shared data client-side
On the client, Inertia exposes page props through usePage(). Shared values appear under the shared key. This React example reads the shared user and flash message inside a layout component:
import { usePage } from '@inertiajs/react';
import { Link } from '@inertiajs/react';
export default function AppLayout({ children }) {
const page = usePage();
const user = page.props.shared?.['auth.user'] ?? null;
const flash = page.props.shared?.flash ?? {};
return (
<main>
{flash.success && <div role="alert">{flash.success}</div>}
<nav>
{user ? <span>Signed in as {user.name}</span> : <Link href="/login">Sign in</Link>}
</nav>
{children}
</main>
);
}
Vue 3 clients use the same shape through usePage() from @inertiajs/vue3; the property path is identical.
How shared data merges with page props
Inertia merges shared data into the page JSON before sending it to the browser. Controller props take precedence over shared props with the same key. The browser receives one JSON object per visit; shared keys are not fetched separately.
Limits and common mistakes
- Payload size. Shared data is serialized into every Inertia response. A large shared object increases every page visit, even when only one component needs it. Keep shared data to primitives, IDs, or small arrays.
- Secrets and PII. Never share passwords, access tokens, or personal identifiers unless every page genuinely needs them. Shared data is visible in the page JSON sent to the browser.
- Non-serializable values. Do not share Eloquent models, database connections, or open file handles. Transform models to arrays or explicit primitives first.
- Client mutations are discarded. Changing
usePage().props.sharedin the browser does not update the server or survive the next Inertia visit. Shared data is not a reactive client store. - Expensive callbacks. A closure in
share()runs on every Inertia request. Avoid uncached queries or heavy computation inside it.
Verification
- Open your application in a browser and open the Network tab.
- Filter requests by the
X-Inertiaheader or visit a page that uses Inertia. - Inspect the response JSON and confirm it contains a
sharedobject with the keys you configured. - Visit another Inertia page and confirm the same shared keys appear.
- Log in and out, then check
usePage().props.shared.auth.userin a root layout to confirm it reflects the current session. - Compare response body size with and without a large shared collection in a production-like build to measure payload impact.
Reverting the change
Because this configuration only changes middleware state, rollback consists of removing the added keys from the share method or removing the custom middleware binding. No database migration is involved.
When not to use shared data
Use controller props for data needed by only one page. Use shared data only when the same value is genuinely required across many pages and the payload cost is acceptable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.