Skip to content
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

Deferred props can't be SSR'd #2150

Open
JenteSL opened this issue Dec 22, 2024 · 2 comments
Open

Deferred props can't be SSR'd #2150

JenteSL opened this issue Dec 22, 2024 · 2 comments

Comments

@JenteSL
Copy link

JenteSL commented Dec 22, 2024

Versions:

  • @inertiajs/core version: 2.0.0
  • @inertiajs/react version: 2.0.0

Describe the problem:

When enabling server-side rendering (SSR) and disabling JavaScript in the browser, <Deferred /> components are displayed using their fallback component instead of the resolved children.

I believe this is because the Router's loadDeferredProps relies on reload, which is a browser-only method.

Is there a workaround for resolving the <Deferred /> components when server-side rendering?


Steps to reproduce:

In a new Laravel example with Inertia + React installed (using default app.jsx and ssr.jsx):

# routes/web.php

Route::get('/message', function () {
    return Inertia::render('Message', [
        'message' => Inertia::defer(fn () => 'Hello world'),
    ]);
});
// resources/js/Pages/Message.jsx

import { Deferred } from '@inertiajs/react'

export default function Message({ message }) {
    return (
        <Deferred data="message" fallback={<p>Loading...</p>}>
            <DeferredMessage />
        </Deferred>
    );
}

import { usePage } from '@inertiajs/react'

function DeferredMessage() {
    const message = usePage().props.message;

    return (
        <p>
            {message}
        </p>
    );
}

Then when doing a vite build (a regular one and an --ssr one, using npm run build) and starting the ssr-server (using php artisan inertia:start-ssr), going to '/message` will show up as:

Loading...

instead of:

Hello world
@RobertBoes
Copy link
Contributor

Wouldn't this be desired behavior (intended or not)? Deferred props are used to defer loading of props, mostly for performance benefits. If during SSR they would be loaded then the initial response would take longer, defeating the purpose of using deferred props

@JenteSL
Copy link
Author

JenteSL commented Dec 23, 2024

Thanks for the answer.

So I learned something—it makes sense for the Deferred components to show the fallback as a server-rendered starting point that then gets hydrated + completed (fetching the deferred props).

Coming from Remix, I thought the behavior there was different as to allow search engines to index the full page (including resolved deferred components).

But it turns out that Remix also shows the fallback when disabling JavaScript in the browser. To allow search engines to index the full page, they instead rely on checking whether the request comes from a bot and, if so, return the full HTML document.

For this they use a React streaming API that waits for all content to be loaded.

But since Inertia’s deferred properties are not actually streaming, but partial reloads, maybe there isn't an easy solution to wait for all content to be loaded in the case of a bot?

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

No branches or pull requests

2 participants