@@ -12,17 +12,21 @@ import { SpanStatusCode } from "@opentelemetry/api";
1212import type { ResolvedFreshConfig } from "./config.ts" ;
1313import type { BuildCache } from "./build_cache.ts" ;
1414import type { LayoutConfig } from "./types.ts" ;
15- import { RenderState , setRenderState } from "./runtime/server/preact_hooks.tsx" ;
16- import { PARTIAL_SEARCH_PARAM } from "./constants.ts" ;
15+ import {
16+ FreshScripts ,
17+ RenderState ,
18+ setRenderState ,
19+ } from "./runtime/server/preact_hooks.tsx" ;
20+ import { DEV_ERROR_OVERLAY_URL , PARTIAL_SEARCH_PARAM } from "./constants.ts" ;
1721import { tracer } from "./otel.ts" ;
1822import {
1923 type ComponentDef ,
2024 isAsyncAnyComponent ,
2125 type PageProps ,
22- preactRender ,
2326 renderAsyncAnyComponent ,
2427 renderRouteComponent ,
2528} from "./render.ts" ;
29+ import { renderToString } from "preact-render-to-string" ;
2630
2731export interface Island {
2832 file : string ;
@@ -278,22 +282,47 @@ export class Context<State> {
278282 try {
279283 setRenderState ( state ) ;
280284
281- const inner = preactRender (
285+ let html = renderToString (
282286 vnode ?? h ( Fragment , null ) ,
283- this ,
284- state ,
285- ! hasApp ,
286287 ) ;
287288
288- if ( ! hasApp ) {
289- return inner ;
289+ if ( hasApp ) {
290+ appChild = jsxTemplate ( [ html ] ) ;
291+ html = renderToString ( appVNode ) ;
290292 }
291293
292- appChild = jsxTemplate ( [ inner ] ) ;
293-
294- const outer = preactRender ( appVNode , this , state , true ) ;
294+ if (
295+ ! state . renderedHtmlBody || ! state . renderedHtmlHead ||
296+ ! state . renderedHtmlTag
297+ ) {
298+ let fallback : VNode = jsxTemplate ( [ html ] ) ;
299+ if ( ! state . renderedHtmlBody ) {
300+ let scripts : VNode | null = null ;
301+
302+ if (
303+ this . url . pathname !== this . config . basePath + DEV_ERROR_OVERLAY_URL
304+ ) {
305+ scripts = h ( FreshScripts , null ) as VNode ;
306+ }
307+
308+ fallback = h ( "body" , null , fallback , scripts ) ;
309+ }
310+ if ( ! state . renderedHtmlHead ) {
311+ fallback = h (
312+ Fragment ,
313+ null ,
314+ h ( "head" , null , h ( "meta" , { charset : "utf-8" } ) ) ,
315+ fallback ,
316+ ) ;
317+ }
318+ if ( ! state . renderedHtmlTag ) {
319+ fallback = h ( "html" , null , fallback ) ;
320+ }
321+
322+ html = renderToString ( fallback ) ;
323+ }
295324
296- return outer ;
325+ return `<!DOCTYPE html> ${ html } ` ;
297326 } catch ( err ) {
298327 if ( err instanceof Error ) {
299328 span . recordException ( err ) ;
0 commit comments