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

Server-side Rendering (without hydration) #2335

Merged
merged 31 commits into from
Jan 12, 2022
Merged

Conversation

futursolo
Copy link
Member

@futursolo futursolo commented Jan 6, 2022

Description

This PR introduces a ServerRenderer that can be used to render a Component into a String.

The primary difference between the original API outlined in #1154 and this PR is that render() is an async fn which supports data-fetching during the rendering process via <Suspense />.

One caveat is that render() is !Send due to the use of Rc and RefCell throughout the entire library (and fields containing web_sys structs such as Element). This may cause issues when trying to use Yew with libraries that require a Future + Send future but can be worked around.
I think there's not a big enough incentive to replace everything with their sync counterpart so I have decided to make render !Send.

Most Web APIs are not gated and will be compiled in as-is when used on non-wasm targets.
Due to the following reasons:

  1. The number of feature flag will be large with very little technical gain. (You cannot make Yew Send with only removal of Web APIs anyways.)
  2. It's not possible to have the same API (e.g: NodeRef) on both server side and client side if web_sys is not allowed. Hence requires developer to also use feature flags to distinguish between client side and server side. I see very little reason to use feature flags if a boundary of client-side only logics can be easily established with use_effect.
    (Using feature flags can be annoying from time to time as it sometimes can be easily forgotten and it's fairly easy to trigger false positive lints like unused_variables, etc.)

Fixes #1154
Fixes #1155

I have noticed that #2330 is filed in the meanwhile and I anticipate to take some time before a decision can be made on it.
So I have decided to file the server-side rending part first which should be easy to solve conflict should either this PR or #2330 is merged first. And see how #2330 goes before I work on the hydration part.

Checklist

  • I have run cargo make pr-flow
  • I have reviewed my own code
  • I have added tests

@github-actions
Copy link

github-actions bot commented Jan 6, 2022

Visit the preview URL for this PR (updated for commit 3567689):

https://yew-rs--pr2335-ssr-fuscyfij.web.app

(expires Wed, 19 Jan 2022 13:51:11 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@voidpumpkin
Copy link
Member

I just read the title and already my reaction is 😲

@voidpumpkin voidpumpkin added the A-yew Area: The main yew crate label Jan 6, 2022
@ranile ranile added this to the v0.20 milestone Jan 6, 2022
@Madoshakalaka
Copy link
Contributor

🤯 🤯 🤯 🤯 🤯 🤯 🤯 🤯 thank you!

@sansx
Copy link
Contributor

sansx commented Jan 7, 2022

wow, it's historical moment 😆

@voidpumpkin
Copy link
Member

@futursolo Could you convert this into a draft if its not ready to be reviewed? I keep seeing new commits.

@futursolo
Copy link
Member Author

futursolo commented Jan 7, 2022

@futursolo Could you convert this into a draft if its not ready to be reviewed? I keep seeing new commits.

it's ready since I submitted it.

I am just doing some improvement on the docs so ssr would show as a feature flag as nobody is reviewing it at the moment.

(If you keep seeing notifications, I am sorry. I guess I will stop doing it.)

image

Copy link
Member

@ranile ranile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how routing would handed. yew-router can't work with SSR

packages/yew/Cargo.toml Show resolved Hide resolved
packages/yew/src/lib.rs Outdated Show resolved Hide resolved
packages/yew/src/suspense/suspension.rs Show resolved Hide resolved
packages/yew/src/virtual_dom/vcomp.rs Show resolved Hide resolved
packages/yew/src/virtual_dom/vcomp.rs Show resolved Hide resolved
packages/yew/src/lib.rs Outdated Show resolved Hide resolved
packages/yew/src/io_coop.rs Show resolved Hide resolved
@voidpumpkin
Copy link
Member

I am so sorry I'm taking so long to review this.
Its just that want to test the API for myself by creating a testing app, but haven't had the time yet...

@ranile
Copy link
Member

ranile commented Jan 11, 2022

I am so sorry I'm taking so long to review this.
Its just that want to test the API for myself by creating a testing app, but haven't had the time yet...

@voidpumpkin, I'd say that testing the API can be done any time before release. How about you review the code changes and leave the rest for later (when hydration is in place)?

@voidpumpkin
Copy link
Member

voidpumpkin commented Jan 11, 2022

@futursolo Could you split out simple ssr example to only have one component per file.
Also main.rs should only have the main function and no components.

@futursolo
Copy link
Member Author

@futursolo Could you split out simple ssr example to only have one component per file.
Also main.rs should only have the main function and no components.

I don't think this is a good thing to do and most examples don't follow this rule either.

one component per file

I am not writing Java or Angular, am I?

@voidpumpkin
Copy link
Member

@futursolo Could you split out simple ssr example to only have one component per file.
Also main.rs should only have the main function and no components.

I don't think this is a good thing to do and most examples don't follow this rule either.

one component per file

I am not writing Java or Angular, am I?

I guess its just a preference. Ok i wont block the pr because of this

voidpumpkin
voidpumpkin previously approved these changes Jan 11, 2022
Copy link
Member

@voidpumpkin voidpumpkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me some time because i have little experience with ssr. But from what i gather i don't see any issues at the moment.

// But you can create a sidebar manually
sidebar: [
// But you can create a sidebar manually
sidebar: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we seriously need to add a formatting hook to commits as every person keeps formatting this file differently.

ranile
ranile previously approved these changes Jan 11, 2022
@ranile
Copy link
Member

ranile commented Jan 11, 2022

There's conflicts...

# Conflicts:
#	packages/yew/Cargo.toml
@futursolo futursolo dismissed stale reviews from ranile and voidpumpkin via 0f24ae6 January 11, 2022 22:44
voidpumpkin
voidpumpkin previously approved these changes Jan 11, 2022
@@ -0,0 +1,6 @@
# Server-side Rendering Example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You forgot to add your example in the table in examples/README.md
But don't add it now, I'm changing that table so ill just add it in my PR.

# Conflicts:
#	packages/yew/src/lib.rs
Copy link
Member

@ranile ranile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited to get this merged!

@ranile
Copy link
Member

ranile commented Jan 12, 2022

This was already approved by @voidpumpkin so merging it as 2 review requirement has been met.

@ranile ranile merged commit d8c2550 into yewstack:master Jan 12, 2022
@futursolo futursolo deleted the ssr branch January 27, 2022 14:19
da-x pushed a commit to da-x/yew that referenced this pull request Jul 27, 2022
* Basic render to html implementation.

* Remove HtmlWriter.

* Escape html content.

* Add non-suspense tests.

* Add Suspense tests.

* Gated "ssr" feature.

* Add example.

* Fix tests.

* Fix docs.

* Fix heading size.

* Remove the unused YewRenderer.

* Remove extra comment.

* unify naming.

* Update docs.

* Update docs.

* Update docs.

* Isolate spawn_local.

* Add doc flags.

* Add ssr feature to docs.

* Move ServerRenderer into their own file.

* Fix docs.

* Update features and docs.

* Fix example.

* Adjust comment position.

* Fix effects being wrongly called when a component is suspended.

* Fix clippy.

* Uuid & no double boxing.

Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-yew Area: The main yew crate
Projects
Status: Done
6 participants