Skip to content

[2.x] Add initial Shared Prop Support for Initial Page Load #760

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

Open
wants to merge 4 commits into
base: 2.x
Choose a base branch
from

Conversation

michaelnabil230
Copy link

@michaelnabil230 michaelnabil230 commented Jul 12, 2025

This PR adds support for an initial prop option in Inertia.js shared props. It allows developers to define props that should be sent only with the initial page load and excluded from subsequent Inertia responses.

This enhancement is particularly useful for values like configuration settings, application metadata, or other static data that doesn't need to be included with every request — reducing payload size and improving response efficiency.

Example:

public function share(Request $request): array
{
    return [
        ...parent::share($request),
        'user' => auth()->user(),
        'locale' => Inertia::initial(fn() => 'en'),
        'appName' => Inertia::initial(fn() => 'Test App'),
        'translations' => Inertia::initial(fn() => [
            'en' => 'English',
            'es' => 'Spanish',
        ]),
    ];
}

In this example, the defined props (locale, appName, translations) will be shared only on the first Inertia response.

Why this matters:

As discussed in Inertia.js Discussion #993, there's a recurring need to send certain props — such as app settings, tokens, or translation strings — only with the initial page load, during the app's initial load. This feature provides a clean, built-in solution for that use case.

Note

If this PR proves useful and is approved for integration, I'd be happy to work on adding the corresponding support in the Inertia.js client-side adapter as well.

@pascalbaljet
Copy link
Member

Interesting idea! Can't we just introduce an Inertia::once() or Inertia::initial() that checks request()->inertia() for the header? If it's missing, you know it's the initial page load. This way, we can reuse the share() method in the Middleware. Not sure about the method name yet.

@michaelnabil230 michaelnabil230 changed the title [2.x] Add once Shared Prop Support for Initial Page Load [2.x] Add initial Shared Prop Support for Initial Page Load Jul 15, 2025
@michaelnabil230
Copy link
Author

Thanks — I really like that idea as well.

I agree that initial() is a better method name since it clearly conveys that the prop is for the initial request only, rather than implying a global one-time execution like once() might.

I’ve also updated the code to integrate initial directly into the share() method within the middleware.

@pascalbaljet
Copy link
Member

What do you have in mind for the frontend? I've played around with it, and is your idea that you're using this in the createInertiaApp.setup block?

createInertiaApp({
  setup({ el, App, props, plugin }) {
    const { translations } = props.initialPage.initialProps // <=

    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

@pascalbaljet pascalbaljet added the needs more info/work Needs more info from the author or additional work to get merged label Jul 17, 2025
@michaelnabil230
Copy link
Author

michaelnabil230 commented Jul 17, 2025

Thanks for sharing your thoughts! For the frontend, I'm indeed working within the createInertiaApp.setup block to set up the Inertia.js app with Vue. Here's how I'm approaching it:

createInertiaApp({
  title: (title, initialProps) => `${title} - ${initialProps.appName || 'MyApp'}`,
  setup({ el, App, props, plugin, initialProps }) {
    const { appName, translations } = initialProps;

    console.log('App Name:', appName); // For debugging

    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el);
  },
});

A few notes on the setup:

  • Title: Added a dynamic title callback that uses appName from initialProps.
  • Setup: I'm accessing appName and translations from initialProps (as you mentioned in your example with translations).

Note

There’s no need to include initialProps in the props, as it's not relevant in this context.

Let me know if you have specific plans for frontend logic!

@michaelnabil230
Copy link
Author

michaelnabil230 commented Jul 17, 2025

While working with Inertia.js, I discovered that we can define the initialPropsResolver directly in the HandleInertiaRequests middleware like this:

public function initialPropsResolver(): array
{
    return function (Request $request) {
        return [
            'locale' => 'en',
            'appName' => 'Test App',
            'translations' => [
                'en' => 'English',
                'es' => 'Spanish',
            ],
        ];
    };
}

Previous approach using share() and Inertia::initial():

public function share(Request $request): array
{
    return [
        ...parent::share($request),
        'user' => auth()->user(),
        'locale' => Inertia::initial(fn() => 'en'),
        'appName' => Inertia::initial(fn() => 'Test App'),
        'translations' => Inertia::initial(fn() => [
            'en' => 'English',
            'es' => 'Spanish',
        ]),
    ];
}

Note

In the old approach, developers might unintentionally misuse Inertia::initial()—for example, by calling Inertia::share() inside a controller:

class UserController
{
    public function __invoke(): void
    {
        Inertia::share(['initial' => Inertia::initial(fn() => true)]);

        return inertia('Users/Index', [
            'users' => User::all(),
        ]);
    }
}

This can lead to unexpected behavior where the shared initial values are missing on the first request or only appear after a full page refresh. This inconsistency can confuse developers and result in props not being available when expected.

Would it be more reliable to centralize these values using initialPropsResolver instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs more info/work Needs more info from the author or additional work to get merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants