Skip to content

Add documentation for props and the new ProvidesInertiaProperty and ProvidesInertiaProperties interfaces #442

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

Merged
merged 4 commits into from
Aug 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 227 additions & 3 deletions resources/js/Pages/responses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export const meta = {
title: 'Responses',
links: [
{ url: '#creating-responses', name: 'Creating responses' },
{ url: '#properties', name: 'Properties' },
{ url: '#provides-inertia-property', name: 'ProvidesInertiaProperty interface' },
{ url: '#provides-inertia-properties', name: 'ProvidesInertiaProperties interface' },
{ url: '#root-template-data', name: 'Root template data' },
{ url: '#maximum-response-size', name: 'Maximum response size' },
],
Expand All @@ -18,10 +21,10 @@ export default function () {
<P>
Creating an Inertia response is simple. To get started, invoke the <Code>Inertia::render()</Code> method within
your controller or route, providing both the name of the <A href="/pages">JavaScript page component</A> that you
wish to render, as well as any props (data) for the page.
wish to render, as well as any properties (data) for the page.
</P>
<P>
In the example below, we will pass a single prop (<Code>event</Code>) which contains four attributes (
In the example below, we will pass a single property (<Code>event</Code>) which contains four attributes (
<Code>id</Code>, <Code>title</Code>, <Code>start_date</Code> and <Code>description</Code>) to the{' '}
<Code>Event/Show</Code> page component.
</P>
Expand Down Expand Up @@ -66,6 +69,227 @@ export default function () {
To ensure that pages load quickly, only return the minimum data required for the page. Also, be aware that all
data returned from the controllers will be visible client-side, so be sure to omit sensitive information.
</Notice>
<H2>Properties</H2>
<P>
To pass data from the server to your page components, you can use properties. You can pass various types of values as
props, including primitive types, arrays, objects, and several Laravel-specific types that are automatically resolved:
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
use App\\Models\\User;
use Illuminate\\Http\\Resources\\Json\\JsonResource;

Inertia::render('Dashboard', [
// Primitive values
'title' => 'Dashboard',
'count' => 42,
'active' => true,

// Arrays and objects
'settings' => ['theme' => 'dark', 'notifications' => true],

// Arrayable objects (Collections, Models, etc.)
'user' => auth()->user(), // Eloquent model
'users' => User::all(), // Eloquent collection

// API Resources
'profile' => new UserResource(auth()->user()),

// Responsable objects
'data' => new JsonResponse(['key' => 'value']),

// Closures
'timestamp' => fn() => now()->timestamp,
]);
`,
},
]}
/>
<P>
Arrayable objects like Eloquent models and collections are automatically converted using their <Code>toArray()</Code> method.
Responsable objects like API resources and JSON responses are resolved through their <Code>toResponse()</Code> method.
</P>
<H2>ProvidesInertiaProperty interface</H2>
<P>
When passing props to your components, you may want to create custom classes that can transform themselves into the
appropriate data format. While Laravel's <Code>Arrayable</Code> interface simply converts objects to arrays, Inertia
offers the more powerful <Code>ProvidesInertiaProperty</Code> interface for context-aware transformations.
</P>
<P>
This interface requires a <Code>toInertiaProperty</Code> method that receives a <Code>PropertyContext</Code> object
containing the property key (<Code>$context->key</Code>), all props for the page (<Code>$context->props</Code>), and the
request instance (<Code>$context->request</Code>).
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
use Inertia\\PropertyContext;
use Inertia\\ProvidesInertiaProperty;

class UserAvatar implements ProvidesInertiaProperty
{
public function __construct(protected User $user, protected int $size = 64) {}

public function toInertiaProperty(PropertyContext $context): mixed
{
return $this->user->avatar
? Storage::url($this->user->avatar)
: "https://ui-avatars.com/api/?name={$this->user->name}&size={$this->size}";
}
}
`,
},
]}
/>
<P>
You can use this class directly as a prop value:
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
Inertia::render('Profile', [
'user' => $user,
'avatar' => new UserAvatar($user, 128),
]);
`,
},
]}
/>
<P>
The <Code>PropertyContext</Code> gives you access to the property key, which enables powerful patterns like merging
with shared data:
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
use Inertia\\Inertia;
use Inertia\\PropertyContext;
use Inertia\\ProvidesInertiaProperty;

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

public function toInertiaProperty(PropertyContext $context): mixed
{
// Access the property key to get shared data
$shared = Inertia::getShared($context->key, []);

// Merge with the new items
return array_merge($shared, $this->items);
}
}

// Usage
Inertia::share('notifications', ['Welcome back!']);

return Inertia::render('Dashboard', [
'notifications' => new MergeWithShared(['New message received']),
// Result: ['Welcome back!', 'New message received']
]);
`,
},
]}
/>
<H2>ProvidesInertiaProperties interface</H2>
<P>
In some situations you may want to group related props together for reusability across different pages. You can
accomplish this by implementing the <Code>ProvidesInertiaProperties</Code> interface.
</P>
<P>
This interface requires a <Code>toInertiaProperties</Code> method that returns an array of key-value pairs. The
method receives a <Code>RenderContext</Code> object containing the component name (<Code>$context->component</Code>)
and request instance (<Code>$context->request</Code>).
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
use App\\Models\\User;
use Illuminate\\Container\\Attributes\\CurrentUser;
use Inertia\\RenderContext;
use Inertia\\ProvidesInertiaProperties;

class UserPermissions implements ProvidesInertiaProperties
{
public function __construct(#[CurrentUser] protected User $user) {}

public function toInertiaProperties(RenderContext $context): array
{
return [
'canEdit' => $this->user->can('edit'),
'canDelete' => $this->user->can('delete'),
'canPublish' => $this->user->can('publish'),
'isAdmin' => $this->user->hasRole('admin'),
];
}
}
`,
},
]}
/>
<P>
You can use these prop classes directly in the <Code>render()</Code> and <Code>with()</Code> methods:
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
public function index(UserPermissions $permissions)
{
return Inertia::render('UserProfile', $permissions);

// or...

return Inertia::render('UserProfile')->with($permissions);
}
`,
},
]}
/>
<P>
You can also combine multiple prop classes with other props in an array:
</P>
<TabbedCode
examples={[
{
name: 'Laravel',
language: 'php',
code: dedent`
public function index(UserPermissions $permissions)
{
return Inertia::render('UserProfile', [
'user' => auth()->user(),
$permissions,
]);

// or using method chaining...

return Inertia::render('UserProfile')
->with('user', auth()->user())
->with($permissions);
}
`,
},
]}
/>
<H2>Root template data</H2>
<P>
There are situations where you may want to access your prop data in your application's root Blade template. For
Expand All @@ -84,7 +308,7 @@ export default function () {
]}
/>
<P>
Sometimes you may even want to provide data to the root template that will not be sent to your JavaScript page /
Sometimes you may even want to provide data to the root template that will not be sent to your JavaScript page
component. This can be accomplished by invoking the <Code>withViewData</Code> method.
</P>
<TabbedCode
Expand Down