Skip to content

Commit e52f944

Browse files
committed
fix(preact)!: each head manager for each route
1 parent fad6ec2 commit e52f944

3 files changed

Lines changed: 18 additions & 12 deletions

File tree

packages/preact/src/entry-server.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { useContext } from "preact/hooks";
21
import renderToString from "preact-render-to-string";
32
import type { ComponentType } from "preact";
43
import type { Context, RouteModule } from "@impalajs/core";
5-
import { HeadContext } from "./head-context";
4+
import { HeadContext, HeadManager } from "./head-context";
65

7-
function HeadContent() {
8-
const headProvider = useContext(HeadContext);
9-
return <>{...headProvider.getHead()}</>;
6+
function HeadContent({ headManager }: { headManager: HeadManager }) {
7+
return <>{...headManager.getHead()}</>;
108
}
119

1210
export async function render(
@@ -16,13 +14,21 @@ export async function render(
1614
) {
1715
const { default: Page } = await mod();
1816

19-
const body = renderToString(<Page {...context} />);
17+
// We create a new head manager for each request to avoid sharing state across routes
18+
const headManager = new HeadManager();
19+
20+
const body = renderToString(
21+
<HeadContext.Provider value={headManager}>
22+
<Page {...context} />
23+
</HeadContext.Provider>
24+
);
2025

2126
const modules = bootstrapModules?.map(
2227
(m) => `<script type="module" src="${m}"></script>`
2328
);
2429

25-
const headContent = renderToString(<HeadContent />);
30+
// We then pass the head manager instance that is specific to this request to SSR
31+
const headContent = renderToString(<HeadContent headManager={headManager} />);
2632

2733
return {
2834
body,

packages/preact/src/head-context.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createContext, VNode } from "preact";
22

3-
class HeadProvider {
3+
export class HeadManager {
44
private head: VNode<any>[] = [];
55

66
private removeTag(tag: string) {
@@ -31,6 +31,6 @@ class HeadProvider {
3131
}
3232
}
3333

34-
const headProvider = new HeadProvider();
34+
const defaultHeadProvider = new HeadManager();
3535

36-
export const HeadContext = createContext(headProvider);
36+
export const HeadContext = createContext(defaultHeadProvider);

packages/preact/src/head.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { useContext } from "preact/hooks";
1+
import { useContext, useRef } from "preact/hooks";
22
import type { FunctionComponent, VNode } from "preact";
3-
import { HeadContext } from "./head-context";
3+
import { HeadManager, HeadContext } from "./head-context";
44

55
interface HeadProps {
66
title?: string;

0 commit comments

Comments
 (0)