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

Handle hydration inside hydration (resolve nested hydration) #244

Open
dmitrysmagin opened this issue Apr 28, 2022 · 4 comments · May be fixed by #258
Open

Handle hydration inside hydration (resolve nested hydration) #244

dmitrysmagin opened this issue Apr 28, 2022 · 4 comments · May be fixed by #258
Labels
bug Something isn't working

Comments

@dmitrysmagin
Copy link

I have a following scenario:
There are some pages with several hydrated components.
However, I need two variants of site build: 'live-update' and 'static'.
Live-update will monitor some data from CMS system and re-render the page if the data there changes without the need to rebuild the whole site. For this purpose I need the whole page to be a hydrated component, and that's where the problem of nested hydration comes.

The scheme to handle this is the following. There's a wrapper in route template:

{#if process.env.LIVE_UPDATE}
    <ComponentPage hydrate-client={{ prop: null }} />
{:else}
    <ComponentPage prop={null} />
{/if}

And now to resolve nested components inside ComponentPage another wrapper is needed:

{#if process.env.componentType === 'server'}
    <NestedComponent hydrate-client={{ prop2: null }} />
{:else}
    <NestedComponent prop2={null} />
{/if}

However, this brings error in @elderjs/elderjs/build/partialHydration/mountComponentsInHtml.js with this piece of code:

        if (hydrateOptions) {
            throw new Error(`Client side hydrated component is attempting to hydrate another sub component "${hydrateComponentName}." This isn't supported. \n
             Debug: ${JSON.stringify({
                hydrateOptions,
                hydrateComponentName,
                hydrateComponentProps,
                hydrateComponentOptions,
            })}
            `);
        }

What's curious, this code could be commented out and everything will work as expected, because, in fact, nested hydration never actually happens (process.env.componentType resolves this).

Keeping all that above in mind, I'd like to ask if it's possible to make this behavior default or automatic without a wrapper.
So, hydrate-client={{prop: null}} will automatically be changed into prop={null} for all nested hydrated components, or, at least gave only a warning.

@eight04
Copy link
Contributor

eight04 commented Apr 28, 2022

Looks like something I was trying to solve in 23ddb74#diff-8dbdaa04b760b0b6f61e99750b86f672deb58b0f165df0dac1416e941e89832fR24 - let svelte compiler handle the template for loading another (hydrated) component using {#if options.loading ...}.

In that commit, you can use the loading options to control its behavior:

<ComponentPage hydrate-client={{ prop: null }} hydrate-options={{loading: process.env.LIVE_UPDATE ? 'lazy' : 'none'}} />
<NestedComponent hydrate-client={{ prop2: null }} hydrate-options={{loading: process.env.componentType === "server" ? "lazy" : "none"}} />

But then it was reverted. In the future Elderjs will be able to load hydrated components from multiple frameworks, so writing something like <SimpleVueComponent /> in svelte template doesn't really make sense.

Or we have to improve the template to something like:

{#if hydrateOptions.loading === 'none' && componentType === 'svelte'}
  ... insert component literally ...
{#else}
  ... insert partial hydration placeholder ...
{/if}

Just have to scan the file tree to determine component type from its name.

@eight04 eight04 added the bug Something isn't working label Nov 4, 2022
@eight04
Copy link
Contributor

eight04 commented Nov 4, 2022

As a quick fix, maybe we can change that error into a warning so it won't interrupt the build.

@eight04
Copy link
Contributor

eight04 commented Nov 6, 2022

Maybe this should be handled at compile time? When compiling client components, we can replace

<Component hydrate-client={props} />

with

<Component {...props} />

instead of

<ejswrapper data-ejs-component="Component" data-ejs-props={JSON.stringify(props)} data-...

@eight04 eight04 linked a pull request Nov 9, 2022 that will close this issue
@eight04
Copy link
Contributor

eight04 commented Nov 9, 2022

Please try #258. You can install that branch by running:

npm install Elderjs/elderjs#fix/nest-hydrate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants