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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃挕 RFC: Add support for client-side only component hydration #751

Closed
1 of 3 tasks
tony-sull opened this issue Jul 19, 2021 · 9 comments
Closed
1 of 3 tasks

馃挕 RFC: Add support for client-side only component hydration #751

tony-sull opened this issue Jul 19, 2021 · 9 comments

Comments

@tony-sull
Copy link
Contributor

tony-sull commented Jul 19, 2021

Background & Motivation

I want to be able to mark a component to only hydrate in the browser

Proposed Solution

<Counter client:only />

Possible solutions

<Counter client:only />

Alternatives considered

Wrapping browser - specific calls in import.meta.env.SSR or undefined checks

Risks, downsides, and/or tradeoffs

Will likely run into #642 since the children wouldn't be included in the server rendered DOM

Open Questions

Is there an easier way to allow this without partial hydration? Would something like Astro.props.browser do the trick?

Detailed Design

During SSR, any component with client:only hydration won't be rendered but will be prepped for client-side hydration as usual.

Good warnings are key here! If a component fails to render during SSR, log a good error message and recommend using client:only if the component depends on browser-specific APIs

Help make it happen!

  • I am willing to submit a PR to implement this change.
  • I am willing to submit a PR to implement this change, but would need some guidance.
  • I am not willing to submit a PR to implement this change.
@natemoo-re
Copy link
Member

client:only? And that's a good point about hydration, we'd need to render a placeholder deterministically, but I'm not sure how we'd do that since we're currently building the hash based on the generated HTML. Will think about this!

@FredKSchott
Copy link
Member

FredKSchott commented Jul 20, 2021

Copying from discussion on Discord: https://discord.com/channels/830184174198718474/845430950191038464/865646524734111784

---
import {Fallback} from 'astro/components';
---
<Fallback>
  <MyReactComponent client:only />
  <MySpinner slot="fallback" />
</Fallback>

Not sure how feasible this is (i don't think it is, actually) but the idea of providing a placeholder/fallback via a slot is interesting!

@matthewp
Copy link
Contributor

@FredKSchott you wrote client:load but I think you mean client:only here.

@FredKSchott
Copy link
Member

Use Case

  • D3 is a good example of a package that has trouble in SSR
  • if I depend on d3 in a component that gets server rendered, that component breaks
  • without this RFC, I have no way to send that component to the browser

RFC Discussion

Does this work without fallback support?

  • a component can already render different on the SSR vs. the client
<div height="200" width="200">
  <MyReactComponent client:only />
</div>
  • another proposal for fallbacks coming from @jasikpark
// Visual.tsx
import Fallback from "Fallback";
if (meta.env.SSR) {
  <Fallback/>
} else {
  let d3 = import('d3'); // https://javascript.info/modules-dynamic-imports
  d3.renderFancyVisual();
}

RFC Decision

  • Approved!

@FredKSchott FredKSchott moved this from Needs Discussion to Accepted in 馃挕 RFC Tracker [No Longer Used] Jul 27, 2021
@tony-sull
Copy link
Contributor Author

We should make sure this will work with #877. I'm guessing support for combining hydration methods will be generic so client:only would bolt right on to any of the other hydration methods, but noting here just in case that RFC may impact the solution here

@matthewp
Copy link
Contributor

@tony-sull Good point. That brings up, when should client:only by itself (without combinators) load? I would assume it would be equivalent to :load.

@jasikpark
Copy link
Contributor

Maybe it shouldn't specify a loading strategy, though in effect the default would be on :load.. so you need to do both client:only and client:visible?

@tony-sull
Copy link
Contributor Author

Yeah I hadn't thought at all about combining hydration modes until I noticed #877 in the RFC tracker. I also was thinking client:only would act the same as :load, and I guess it would combine with other hydrstors just like :load will as well

@matthewp
Copy link
Contributor

Regardless, I think these are questions for #877 to answer, it shouldn't block client:only

馃挕 RFC Tracker [No Longer Used] automation moved this from Accepted to Completed Aug 24, 2021
xstevenyung pushed a commit to xstevenyung/astro that referenced this issue Oct 17, 2023
Co-authored-by: tony-sull <tony-sull@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

No branches or pull requests

5 participants