Skip to content

Commit

Permalink
fix: SSR when rendering multiple "root" component.
Browse files Browse the repository at this point in the history
  • Loading branch information
bfanger committed Oct 20, 2024
1 parent 42e407e commit e10c463
Show file tree
Hide file tree
Showing 15 changed files with 34 additions and 6 deletions.
11 changes: 10 additions & 1 deletion playwright/tests/ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ import { fileURLToPath } from "url";
test.describe.configure({ mode: "serial" });
test.use({ viewport: { width: 480, height: 360 } });
test.describe("ssr", () => {
const urls = ["/context-svelte", "/context-react", "/preprocessor"];
const urls = [
"/context-svelte",
"/context-react",
"/preprocessor",
"/hooks",
"/dynamic",
"/input",
"/react-router/home",
"/react-router/about",
];

test("client-rendered", async ({ page }) => {
// Create Screenshots using Client Side Rendering.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/lib/internal/ReactWrapper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
node.parent.nodes = node.parent.nodes.filter((n: any) => n !== node);
node.rerender?.();
}
node.unroot?.();
});
</script>

Expand Down
1 change: 1 addition & 0 deletions src/lib/internal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type TreeNode = SvelteInit & {
autoKey: number;
nodes: TreeNode[];
rerender?: () => void;
unroot?: () => void;
};

export type SvelteInit = {
Expand Down
1 change: 0 additions & 1 deletion src/lib/preprocessReact.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ function transform(content, options) {
if (!depsInjected && aliases.length === 0) {
return { code: content };
}
// console.log(aliases);
if ((depsInjected && !imported) || (!imported && !defined)) {
imports.push(`import { sveltify } from "${packageName}";`);
}
Expand Down
26 changes: 22 additions & 4 deletions src/lib/sveltify.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,15 @@ function single<T extends React.FC | React.ComponentClass>(
const client = typeof document !== "undefined";

function Sveltified(anchorOrPayload: any, $$props: any) {
const standalone = !sharedRoot;
let standalone = !sharedRoot;
if (!createPortal || !ReactDOM) {
throw new Error("createPortal & ReactDOM dependencies are required");
throw new Error(
"{ createPortal, ReactDOM } are not injected, check svelte.config.js for: `preprocess: [preprocessReact()],`",
);
}

$$props.svelteInit = (init: SvelteInit) => {
let unroot: undefined | (() => void);
if (!init.parent && !sharedRoot) {
let portalTarget = $state<HTMLElement | undefined>();
const hooks = $state<{ Hook: React.FunctionComponent; key: number }[]>(
Expand All @@ -121,6 +124,17 @@ function single<T extends React.FC | React.ComponentClass>(
},
};
sharedRoot = rootNode;
if (!client) {
unroot = () => {
sharedRoot = undefined;
};
void Promise.resolve().then(() => {
if (sharedRoot === rootNode) {
console.warn("unroot() was not called, did rendering fail?");
sharedRoot = undefined;
}
});
}
if (client) {
const rootEl = document.createElement("react-root");
const root =
Expand Down Expand Up @@ -148,7 +162,11 @@ function single<T extends React.FC | React.ComponentClass>(
}
}
}
const parent = init.parent ?? (sharedRoot as TreeNode);
let parent = init.parent;
if (!parent) {
parent = sharedRoot as TreeNode;
standalone = true;
}
parent.autoKey += 1;
const key = `${parent.key}${parent.autoKey}/`;
const node: TreeNode = Object.assign(init, {
Expand All @@ -157,6 +175,7 @@ function single<T extends React.FC | React.ComponentClass>(
reactComponent,
nodes: [],
rerender: parent.rerender,
unroot,
});
parent.nodes.push(node);
if (client) {
Expand All @@ -177,7 +196,6 @@ function single<T extends React.FC | React.ComponentClass>(
applyPortals(anchorOrPayload, sharedRoot, source);
setPayload(undefined);
}
sharedRoot = undefined;
}
}
return Sveltified as any;
Expand Down

0 comments on commit e10c463

Please sign in to comment.