Skip to content

Commit

Permalink
fix(#3362): fix client:only behavior for React, Vue, Solid
Browse files Browse the repository at this point in the history
  • Loading branch information
Nate Moore committed May 26, 2022
1 parent 362ab17 commit d58e8cc
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 13 deletions.
7 changes: 4 additions & 3 deletions packages/integrations/react/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@ function isAlreadyHydrated(element) {

export default (element) =>
(Component, props, children, { client }) => {
if (!element.hasAttribute('ssr')) return;
const componentEl = createElement(
Component,
props,
children != null ? createElement(StaticHtml, { value: children }) : children
);
if (client === 'only') {
return createRoot(element).render(componentEl);
}
const rootKey = isAlreadyHydrated(element);
// HACK: delete internal react marker for nested components to suppress agressive warnings
if (rootKey) {
delete element[rootKey];
}
if (client === 'only') {
return createRoot(element).render(componentEl);
}
return hydrateRoot(element, componentEl);
};
14 changes: 10 additions & 4 deletions packages/integrations/solid/client.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import { sharedConfig } from 'solid-js';
import { hydrate, createComponent } from 'solid-js/web';
import { hydrate, render, createComponent } from 'solid-js/web';

export default (element) => (Component, props, childHTML) => {
export default (element) => (Component, props, childHTML, { client }) => {
// Prepare global object expected by Solid's hydration logic
if (!window._$HY) {
window._$HY = { events: [], completed: new WeakSet(), r: {} };
}
if (!element.hasAttribute('ssr')) return;

const fn = client === 'only' ? render : hydrate;

// Perform actual hydration
let children;
hydrate(
fn(
() =>
createComponent(Component, {
...props,
get children() {
if (childHTML != null) {
// hydrating
if (sharedConfig.context) children = element.querySelector('astro-fragment');
if (sharedConfig.context) {
children = element.querySelector('astro-fragment');
}

if (children == null) {
children = document.createElement('astro-fragment');
Expand Down
5 changes: 3 additions & 2 deletions packages/integrations/svelte/client.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import SvelteWrapper from './Wrapper.svelte';

export default (target) => {
return (component, props, children) => {
return (component, props, children, { client }) => {
if (!target.hasAttribute('ssr')) return;
delete props['class'];
try {
new SvelteWrapper({
target,
props: { __astro_component: component, __astro_children: children, ...props },
hydrate: true,
hydrate: client !== 'only',
});
} catch (e) {}
};
Expand Down
15 changes: 11 additions & 4 deletions packages/integrations/vue/client.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { h, createSSRApp } from 'vue';
import { h, createSSRApp, createApp } from 'vue';
import StaticHtml from './static-html.js';

export default (element) => (Component, props, children) => {
export default (element) => (Component, props, children, { client }) => {
delete props['class'];
if (!element.hasAttribute('ssr')) return;

// Expose name on host component for Vue devtools
const name = Component.name ? `${Component.name} Host` : undefined;
const slots = {};
if (children != null) {
slots.default = () => h(StaticHtml, { value: children });
}
const app = createSSRApp({ name, render: () => h(Component, props, slots) });
app.mount(element, true);
if (client === 'only') {
const app = createApp({ name, render: () => h(Component, props, slots) });
app.mount(element, false);
} else {
const app = createSSRApp({ name, render: () => h(Component, props, slots) });
app.mount(element, true);
}
};

0 comments on commit d58e8cc

Please sign in to comment.