Closed RobertBoes closed 1 week ago
I've reviewed the discussions around this topic, and I see the benefits of allowing more flexibility in how the initial data is rendered. I'd like to propose a slight adjustment to enhance the developer experience (DX) while maintaining backward compatibility:
attribute
or script
for rendering initial data.
attribute
is selected, the JSON-encoded props would continue to be rendered in the data-page
attribute, as is currently done, using the @inertia
directive.script
is selected, the props would instead be output as a JavaScript object in a <script>
tag, leveraging the @inertiaHead
directive.createInertiaApp
: Provide a default implementation of the initialData
option in createInertiaApp
that first looks for data in the <script>
tag, and falls back to the data-page
attribute if necessary. This keeps things flexible while allowing users to override the initialData
option if they need a custom approach.This would offer a cleaner and more flexible setup for users who prefer handling their data in a <script>
tag while preserving the current behavior for those who prefer the data-page
attribute.
Not really sure I understand the proposal, you want to either load it from the data attribute or from a script (a predefined window variable?). That would be less flexible to the end-user, right? Or do you mean to pretty much keep this implementation, along with also checking a window variable. So the end user still has the option to overwrite the method and provide their own data?
Just wondering, because we can already pass the page
attribute to createInertiaApp
as seen here https://github.com/inertiajs/inertia/blob/master/packages/svelte/src/lib/createInertiaApp.ts#L40
Wouldn't it be simpler to simply allow methods to be there?
page: string | () => string | () => Promise<string>
Replace
const initialPage = page || JSON.parse(el?.dataset.page ?? '{}')
with
const initialPage = typeof page === "function" ? await page() : (page || JSON.parse(el?.dataset.page ?? '{}'))
usage
createInertiaApp({
page: async () => {
// Do whatever you want
const response = await fetch("/api/initial-load")
return await response.json();
return JSON.parse(document.getElementById("script-id").textContent);
return window.__initial_load__
}
});
There wouldn't be any breaking changes. This wouldn't require any adapter update which is kind of tricky because there is not only the laravel one that needs to follow
Edit
The current proposal is likely to kill current SSR implementation because it currently expect a string to be returned.
@RobertBoes as @jamesst20 mentioned it seems that the current page
argument in createInertiaApp
can already address this use case. My proposal was aimed at improving the developer experience (DX) by not requiring the user to manually add the <script>
tag. Instead, I suggest we add a inertia.pageSource
option to the Laravel adapter and leverage the existing @inertiaHead
directive to output the script tag when this option is set to script
.
The only change inside createInertiaApp
on the adapters would be:
- const initialPage = page || JSON.parse(el.dataset.page)
+ const initialPage = page || window.__inertiaPage || JSON.parse(el.dataset.page)
This way, the library supports the two most common use cases, script and data attribute, out-of-the-box and users would still have the flexibility to override page
if they want to.
@RobertBoes as @jamesst20 mentioned it seems that the current
page
argument increateInertiaApp
can already address this use case. My proposal was aimed at improving the developer experience (DX) by not requiring the user to manually add the<script>
tag. Instead, I suggest we add ainertia.pageSource
option to the Laravel adapter and leverage the existing@inertiaHead
directive to output the script tag when this option is set toscript
.The only change inside
createInertiaApp
on the adapters would be:- const initialPage = page || JSON.parse(el.dataset.page) + const initialPage = page || window.__inertiaPage || JSON.parse(el.dataset.page)
This way, the library supports the two most common use cases, script and data attribute, out-of-the-box and users would still have the flexibility to override
page
if they want to.
That would work but can we expect everyone https://inertiajs.com/community-adapters to update their implementation aswell? I do agree there is increased value into having it supported effortlessly in the backend adapter
I still believe supporting supporting a function/promise has its worth even if this could be done outside the createInertiaApp and passed as a prop
Hey @RobertBoes, I can confirm that this functionality is already supported via the page
option in createInertiaApp
, which allows you to pass the initial page data directly, like so:
createInertiaApp({
page: window.initialPage,
// ...
})
Does this approach satisfy your use case, or is there something additional you're looking to achieve with this PR? Let me know 😉
Hey @pedroborges, yeah looks like that also works. I'll go with that then.
solves #1960 and #1878 (although not through a new request)
This would allow users to customize how the initial data is rendered. Currently it is always added through the
data-page
attribute.With this PR the following is possible;
Then in your main script you'd do the following:
As a note: This would also require a bit of rework for SSR, as that would still output the div with the
data-page
. Haven't gotten to fixing that yet, but if there's no interest in this there's no point in researching that