11import { renderToPipeableStream , renderToStaticMarkup } from "react-dom/server" ;
2- import { ElementType , useContext } from "react" ;
2+ import { ElementType } from "react" ;
33import type { Context , RouteModule } from "@impalajs/core" ;
44import { Writable , WritableOptions } from "node:stream" ;
5- import { HeadContext } from "./head-context" ;
5+ import { HeadContext , HeadManager } from "./head-context" ;
66
77class StringResponse extends Writable {
88 private buffer : string ;
@@ -30,9 +30,8 @@ class StringResponse extends Writable {
3030 }
3131}
3232
33- function HeadContent ( ) {
34- const headProvider = useContext ( HeadContext ) ;
35- return < > { ...headProvider . getHead ( ) } </ > ;
33+ function HeadContent ( { headManager } : { headManager : HeadManager } ) {
34+ return < > { ...headManager . getHead ( ) } </ > ;
3635}
3736
3837export async function render (
@@ -42,22 +41,32 @@ export async function render(
4241) {
4342 const { default : Page } = await mod ( ) ;
4443
44+ // We create a new head manager for each request to avoid sharing state across routes
45+ const headManager = new HeadManager ( ) ;
46+
4547 const response = new StringResponse ( ) ;
4648
47- const { pipe } = renderToPipeableStream ( < Page { ...context } /> , {
48- bootstrapModules,
49- bootstrapScriptContent : `window.___CONTEXT=${ JSON . stringify ( context ) } ;` ,
50- onAllReady ( ) {
51- pipe ( response ) ;
52- } ,
53- onError ( error ) {
54- console . error ( error ) ;
55- } ,
56- } ) ;
49+ const { pipe } = renderToPipeableStream (
50+ // Now on each render, each page will use their own head context instead of default one
51+ (
52+ < HeadContext . Provider value = { headManager } >
53+ < Page { ...context } />
54+ </ HeadContext . Provider >
55+ ) ,
56+ {
57+ bootstrapModules,
58+ bootstrapScriptContent : `window.___CONTEXT=${ JSON . stringify ( context ) } ;` ,
59+ onAllReady ( ) {
60+ pipe ( response ) ;
61+ } ,
62+ onError ( error ) {
63+ console . error ( error ) ;
64+ } ,
65+ } ) ;
5766
5867 const body = await response . getData ( ) ;
5968
60- const head = renderToStaticMarkup ( < HeadContent /> ) ;
69+ const head = renderToStaticMarkup ( < HeadContent headManager = { headManager } /> ) ;
6170
6271 return { body, head } ;
6372}
0 commit comments