Skip to content

Conversation

pascalbaljet
Copy link
Member

@pascalbaljet pascalbaljet commented Jun 16, 2025

This PR introduces an ProvidesInertiaProp interface. It acts more or less the same as Laravel's Illuminate\Contracts\Support\Responsable interface, but tailored to Inertia.

The interface only has one method: toInertiaProp(PropContext $prop). The PropContext class contains info about the key, (partly) transformed props array, and Request instance. I opted for the PropContext class instead of passing arguments to keep the method signature easy and clean, and so that we could extend/improve PropContext later on without breaking the interface.

There are several use-cases where it would be nice if you had a little more info than just the Request instance:

Using the key

In PR #744, there is a request to merge data from the controller into shared data. Currently, you'd do something like this:

Inertia::render('Page', [
    'roles' => array_merge(Inertia::getShared('roles', []), ['additional']),
]);

There's currently no easy way to implement custom prop types. You could add a macro, but that won't help you much. With the new ProvidesInertiaProp, you could introduce a MergeWithSharedProp class in your own codebase:

class MergeWithSharedProp implements ProvidesInertiaProp
{
    public function __construct(protected array $items = []) {}

    public function toInertiaProp(PropContext $prop): mixed
    {
        return array_merge(Inertia::getShared($prop->key, []), $this->items);
    }
}

This would lead to a much cleaner controller.

Inertia::render('Page', [
    'roles' => new MergeWithSharedProp(['additional']),
]);

When combined with macros, you could end up with Inertia::mergeWithShared(['additional']), which is quite nice!

Using the props

There are use-cases when you want to know about the other props when transforming one. I've experienced this firsthand in my Table package. If you use two tables on a page, you need to prefix the query params for things like pagination. Therefore, I now have this solution where you can name your tables:

Inertia::render('Page', [
    'users' => UsersTable::make(), // uses query string without prefix
    'companies' => CompaniesTable::make()->name('companies'),
]);

If the table classes would implement ProvidesInertiaProp, I could inspect whether there are other table instances in the props, and automatically set the names.

@pascalbaljet
Copy link
Member Author

Marked as draft as I have doubts about the Prop class naming.

@pascalbaljet pascalbaljet changed the title [2.x] Introduce InertiaResponsable interface [2.x] Introduce ProvidesInertiaProp interface Jun 17, 2025
@pascalbaljet
Copy link
Member Author

Marked as draft as I have doubts about the Prop class naming.

Renamed it to ProvidesInertiaProp and PropContext.

@pascalbaljet pascalbaljet marked this pull request as ready for review June 17, 2025 06:42
@danmatthews
Copy link

Would be sweet if we could have ProvidesInertiaProps too - to allow multiple named props to be returned, at the moment, we have some handler classes for certain things that do this by implementing a method called getProps in our handler classes:

public function getProps(DonationFlowSession $session): array
{
    return [
        'prop_one' => 'value',
        'prop_two' => Inertia::defer(fn() => 'value2'),
    ];
}

And we unpack these using the ... operator:

$handler = new MyHandlerClass($var);
return Inertia::render('component', [
    'user' => auth()->user(),
    ...$handler->getProps()
]);

But would be interesting to be able to pass:

$handler = new MyHandlerClass($var);
return Inertia::render('component', [
    'user' => auth()->user(),
    $handler
]);

Or even something like:

return Inertia::render('component', [
    'user' => auth()->user(),
])->with($handler);

All the goodies from your use case would be provided - the PropContext being available for example.

@pascalbaljet
Copy link
Member Author

Thanks @danmatthews, that's a very interesting idea! I'm not sure if we could reuse this new interface for it, but it makes me wonder if I should rename it to ProvidesInertiaPropValue (or simply InertiaPropValue), so that we could later on introduce a ProvidesInertiaProps interface that can provide multiple props like you've shown.

@pascalbaljet
Copy link
Member Author

@danmatthews I've opened a PR for this #748

@pascalbaljet
Copy link
Member Author

Renamed ProvidesInertiaProp to ProvidesInertiaProperty + PropContext to PropertyContext

@pascalbaljet pascalbaljet merged commit 091daa7 into 2.x Aug 8, 2025
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants