Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Understanding Shared Data Overrides in Inertia.js

When using Inertia.js in a Laravel application, page-specific data returned from your controller will override shared data with the same key. This can lead to unexpected behavior.

The Setup

Let's say you have a notification system in your Laravel + Inertia.js application. You share notification data across all pages using Inertia's middleware:

// app/Http/Middleware/HandleInertiaRequests.php
public function share(Request $request): array
{
    return [
        'notifications' => [
            'items' => $this->getNotifications(),
            'unread_count' => $this->getUnreadCount(),
            'alerts' => $this->getAlerts()
        ]
    ];
}

This shared data is used in your layout component to display a notification bell with a dropdown:

<!-- AppLayout.vue -->
<NotificationBell 
    :notifications="$page.props.notifications.items"
    :unread-count="$page.props.notifications.unread_count"
/>

The Gotcha

Now, you create a notifications page to display all notifications:

// NotificationController.php
public function index()
{
    return Inertia::render('Notifications/Index', [
        'notifications' => Notification::latest()->get()  // This overwrites shared data!
    ]);
}

You might expect this to work fine since your shared data is always available, but you'll encounter errors because:

  1. The page-specific notifications data completely replaces the shared notifications data
  2. Your layout components still expect the original structure (items, unread_count, etc.)
  3. The new data has a different structure, causing type errors or undefined property access

The Solution

There are two main approaches to fix this:

1. Use Different Keys (Recommended)

// NotificationController.php
public function index()
{
    return Inertia::render('Notifications/Index', [
        'allNotifications' => Notification::latest()->get()  // Different key
    ]);
}
<!-- Notifications/Index.vue -->
<script setup>
defineProps({
    allNotifications: {
        type: Array,
        required: true
    }
});
</script>

2. Maintain the Same Structure (Not recommended)

Change your Controller to use the same structure as in your shared data. This will still override the shared data but as the structure is the same there probably won't be any errors.

// NotificationController.php
public function index()
{
    return Inertia::render('Notifications/Index', [
        'notifications' => [
            'items' => Notification::latest()->get(),
            'unread_count' => Notification::unread()->count(),
            'alerts' => []
        ]
    ]);
}
What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Subscribe to my newsletter

Get new posts when I publish them.

I respect your privacy. Unsubscribe at any time.

Leave a Reply

Your email address will not be published. Required fields are marked *