-
Notifications
You must be signed in to change notification settings - Fork 257
[2.x] Introduce configurable merge strategy for shared props #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.x
Are you sure you want to change the base?
Conversation
e948b6f
to
f95595c
Compare
- Add DeepMergesSharedProps trait to flatten and deep merge overlapping shared props within a single Inertia response - Update ResponseFactory to apply deep merging when rendering components and sharing props
f95595c
to
e511ff2
Compare
This is a significant change in how props are handled, and I would not expect this behavior when using shared props. Merging is also handled in the frontend. I understand the idea of merging data from the controller into shared props, but I believe it should be more explicit if it should even be a feature of this package. |
One example that might break apps is when you share data for a select dropdown: Inertia::share('someOptions', Model::query()->someGeneralScope()->get()); But then, in another controller or middleware (e.g., for an admin section), you would overwrite it: Inertia::render('Dashboard', [
'someOptions' => Model::query()->moreSpecificScope()->get(),
]); |
Thanks for the feedback! Personally, I find the example use-case a bit uncommon. It suggests intentionally sharing global props, then overriding or limiting them in controllers. In my experience, the opposite is more typical: global props provide consistent data (like base permissions, such as access to certain modules within the application), and controllers extend them contextually - for example by adding page-specific permissions. However, I fully agree to your concern. The proposed behavior could be unexpected or unwanted in some scenarios. Making it explicit would definitely help avoid confusion. If you'd like to I’d be happy to revise the PR. What do you think about the following solutions? Option 1:
|
- Adds support for merge strategy pattern when sharing props - Default behavior remains unchanged via `ShallowMergeStrategy` - Allows consumers to override globally or per call with a custom strategy
I've been thinking about this for a couple of days, and I've come up with a new concept that opens up Inertia for use-cases like yours, where you could more or less introduce custom prop types. I've used your example in the PR (#746). |
This PR introduces deep merging functionality for shared Inertia props to address a key limitation in the current server-side adapter behavior.
The proposed change makes prop handling in Laravel Inertia apps more flexible and reliable, aligning actual behavior with Inertia's official documentation.
🚨 Problem
The official documentation states:
While this implies that shared and controller-level props are seamlessly merged, the actual behavior is a shallow merge, causing keys with similar names to be overwritten instead combined.
✅ Solution
This PR introduces a configurable merge strategy for managing shared Inertia props, providing flexibility and control over how props are combined.
ShallowMergeStrategy
DeepMergeStrategy
either globally or on a per-call basisThis allows middleware and controllers to safely contribute to the same shared props without data loss or key collisions.
Changes
MergeStrategy
interface to define merging behavior for shared propsShallowMergeStrategy
as the default merge strategy to preserve existing behaviorDeepMergeStrategy
as an optional merge strategy for recursive mergingsetSharedPropMerger()
method to allow global configuration on runtime of the merge strategyResponseFactory
to support configurable merge strategies when sharing props and rendering componentsWhy this should not be a breaking change
ShallowMergeStrategy