Comments (9)
We have discussed supporting this internally quite a bit but on the team we aren't a 100% sure whether this is the best abstraction and we're on the lookout on what to support. Hence our current recommendation being preact-ssr-prepass.
Historically Pre React 18, the error you are describing happened in React as well, where react-ssr-prepass was introduced to counter-act this, after React 18 it just renders the Suspense
fallback which imho isn't really ideal either 😅
My assumption is that streaming rendering will be the answer here as that could elegantly hook into these boundaries.
EDIT: documenting is a good shout, thank you!
from preact-render-to-string.
Is renderToString documented somewhere? I feel like I've missed something here.
It's the exact same thing as render
, there's no difference. Just switched up the import name to avoid the conflict is all.
from preact-render-to-string.
The good news is that this is super simple to implement in user land.
Here's a (very slightly) modified excerpt from preact-iso/prerender
inserted into your example showing how you could implement this:
import { renderToString } from "preact-render-to-string"
import { Main } from "./main"
const main = async () => {
let tries = 0;
const maxDepth = 10;
const render = () => {
if (++tries > maxDepth) return;
try {
return renderToString(<Main />);
} catch (e) {
if (e && e.then) return e.then(render);
throw e;
}
};
const rendered = await render();
console.log(rendered)
}
from preact-render-to-string.
Alternatively you can use preact-ssr-prepass to do one pass that optimises parallel promises/... so first prepass and then renderToString
from preact-render-to-string.
The good news is that this is super simple to implement in user land.
Here's a (very slightly) modified excerpt from
preact-iso/prerender
inserted into your example showing how you could implement this:import { renderToString } from "preact-render-to-string" import { Main } from "./main" const main = async () => { let tries = 0; const maxDepth = 10; const render = () => { if (++tries > maxDepth) return; try { return renderToString(<Main />); } catch (e) { if (e && e.then) return e.then(render); throw e; } }; const rendered = await render(); console.log(rendered) }
Thank you for your reply, I'll try to create a reproduction of this fix in a separate branch to confirm that this is working and will push the updates to the repository I linked for the issue for people seeking answers like me.
Any reason why an error has been thrown, when this is not really an error but a promise? I'm really curious about the implementation details of this render
function but I somewhat doubt I'll be able to understand any of this internal working.
Is renderToString
documented somewhere? I feel like I've missed something here.
from preact-render-to-string.
Alternatively you can use preact-ssr-prepass to do one pass that optimises parallel promises/... so first prepass and then renderToString
Thank you for your reply.
Makes sense since when testing with a fully-fleged routing application I get this promise-error thingy the first time I try to render the page, and then it renders correctly on subsequent calls to the server.
But it is making Lighthouse crazy if you try to first-request your server with it.
I'll give preact-ssr-prepass a try if it means less implementation from the userland (what would be the ideal solution for me and maybe other non-power users).
from preact-render-to-string.
The way lazy
and other Suspense
mechanics work is basically throwing a Promise upwards at the point of async, this because VDOM is inherently boundary-based which means that if something within a boundary errors or can't render we need to throw
so we can go up to the closest boundary to or react to the error or await the promise.
from preact-render-to-string.
The way
lazy
and otherSuspense
mechanics work is basically throwing a Promise upwards at the point of async, this because VDOM is inherently boundary-based which means that if something within a boundary errors or can't render we need tothrow
so we can go up to the closest boundary to or react to the error or await the promise.
Makes much sense now I see why, thank you very much for your insight!
Any reason why this is not done by default if this is the intended behavior behind Suspense
& lazy
? Or maybe is there some key differences in the implementation between react
& preact
for those component inside preact/compat
?
from preact-render-to-string.
Alternatively you can use preact-ssr-prepass to do one pass that optimises parallel promises/... so first prepass and then renderToString
I can confirm that the preact-ssr-prepass
package is working as intended, even with my own router when rendering on the server a VNode
that has is lazy.
I feel like this can be (and should be) added in the documentation for people wanting to render asynchronous component (even with a custom implementation bound to this repository to not be dependant of any external libraries).
from preact-render-to-string.
Related Issues (20)
- With Nextjs Error: Objects are not valid as a child. Encountered an object with the keys {} HOT 5
- Shallow rendering and parameter object serialization HOT 1
- Rendering shallow makes a Fragment into a <p> HOT 4
- Async Render for Async Components in the tree?
- Behavior for falsy data attributes not same as preact.
- 5.2.5 breaks server side rendering of @preact/signals HOT 2
- renderToString with {pretty: true} causes undesirable newlines with text nodes HOT 1
- Meta charset not rendered as expected HOT 1
- Void elements have whitespace at closing
- Using effects from @preact/signals causes memory leak HOT 2
- CommonJS bundle broken for v6 HOT 1
- unpkg package seems failed HOT 2
- Unable to import shallowRender from preact-render-to-string/jsx due to TypeScript type errors
- preact and htm function does not return html when ssr rendered from mjs file HOT 3
- xlink:href becomes xlink::href
- `options._diff` not called for implicit Fragments HOT 2
- `preact/debug` warnings not thrown because `vnode.__k` is not set
- Stream Rendering Roadmap HOT 2
- Invalid nesting detection with `preact/debug` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from preact-render-to-string.