inertia icon indicating copy to clipboard operation
inertia copied to clipboard

The server used "renderToString" which does not support Suspense

Open ramonmalcolm10 opened this issue 2 years ago • 7 comments

Version:

  • @inertiajs/react version: 1.0.11

Describe the problem:

When using components that are lazy load with React Suspense the following error is thrown in the browser console:

Uncaught Error: The server did not finish this Suspense boundary: The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server

Steps to reproduce:

  • laravel + inertia + react installation with SSR
  • Create a page that uses lazy load and Suspense
import React, { lazy, Suspense } from 'react';

// Lazy load the component
const LazyLoadedComponent = lazy(() => import('./LazyComponent'));

const TestPage = () => {
     return (
        <div>
          <Suspense fallback={<div>Loading...</div>}>
            <LazyLoadedComponent />
          </Suspense>
        </div>
  );
}

export default TestPage;
php artisan inertia:start-ssr
  • Load page in browser and check browser console

ramonmalcolm10 avatar Sep 09 '23 19:09 ramonmalcolm10

I'm trying to do something similar and running into the same issues. Have you managed to find any solutions so far?

shane1090 avatar Sep 22 '23 23:09 shane1090

Unfortunately no, had to remove lazy load. A modification would have to be made to the server file to support streaming response.

ramonmalcolm10 avatar Sep 22 '23 23:09 ramonmalcolm10

Do you know if inertia team is planning to add support for renderToPipelineStream? we are also stuck on the same thing and there is no information about it

mordonez-me avatar Feb 21 '24 13:02 mordonez-me

There is a problem in the ssr file, if possible, send it so we can find the problem. In LazyLoadedComponent, you must export default. and ReactDOMServer.renderToString that work in inertia.

abdorrahmani avatar Apr 09 '24 13:04 abdorrahmani

There is a problem in the ssr file, if possible, send it so we can find the problem. In LazyLoadedComponent, you must export default. and ReactDOMServer.renderToString that work in inertia.

The problem will remain the same. renderToString doesn't support Suspense, so it will not be possible to render any component asynchronously: you can see in caveat section on the React docs

Bricklou avatar Apr 09 '24 13:04 Bricklou

Of course, but I use renderToString without any problems in React 18.

so my ssr file :

import ReactDOMServer from 'react-dom/server';
import { createInertiaApp } from '@inertiajs/react';
import createServer from '@inertiajs/react/server';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import route from '../../vendor/tightenco/ziggy/dist/index.m';

createServer((page) =>
    createInertiaApp({
        page,
        render: ReactDOMServer.renderToString,
        resolve: (name) => resolvePageComponent(`./Pages/${name}.tsx`, import.meta.glob('./Pages/**/*.tsx' , {eager: true})),
        setup: ({ App, props }) => {
            global.route = (name, params, absolute) =>
                route(name, params, absolute, {
                    ...page.props.ziggy,
                    location: new URL(page.props.ziggy.location),
                });

            return <App {...props} />;
        },
    })
);

and app.jsx :

import { hydrateRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';


createInertiaApp({
    resolve: (name) => resolvePageComponent(`./Pages/${name}.tsx`, import.meta.glob('./Pages/**/*.tsx',{eager:true})),
    setup({ el, App, props }) {
        el.removeAttribute("data-page"); // remove attribute
        hydrateRoot(el,<App {...props} />);

    },
    progress: {
        color: '#006aff',
    },
});

so try this..

abdorrahmani avatar Apr 09 '24 15:04 abdorrahmani

@abdorrahmani if you using Suspense on a page with ssr and reload that page you will get a warning in the browser console, It will work nonetheless because it will be handle by the browser. Suspense is normally streamed to the client from the server, renderToString does not support streaming, in fact Inertia.js server file doesn't support streaming either.

ramonmalcolm10 avatar Apr 09 '24 16:04 ramonmalcolm10

I've made a discussion about how this could potentially get implemented #1887

nick-potts avatar Jun 02 '24 12:06 nick-potts

Hi all. This seems to be a feature request. Feel free to focus the discussion in https://github.com/inertiajs/inertia/discussions/1887. If anyone's up to feel free to attempt a PR.

driesvints avatar Jun 03 '24 12:06 driesvints