@@ -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 ;
@@ -281,22 +285,47 @@ export class Context<State> {
281285 try {
282286 setRenderState ( state ) ;
283287
284- const inner = preactRender (
288+ let html = renderToString (
285289 vnode ?? h ( Fragment , null ) ,
286- this ,
287- state ,
288- ! hasApp ,
289290 ) ;
290291
291- if ( ! hasApp ) {
292- return inner ;
292+ if ( hasApp ) {
293+ appChild = jsxTemplate ( [ html ] ) ;
294+ html = renderToString ( appVNode ) ;
293295 }
294296
295- appChild = jsxTemplate ( [ inner ] ) ;
296-
297- const outer = preactRender ( appVNode , this , state , true ) ;
297+ if (
298+ ! state . renderedHtmlBody || ! state . renderedHtmlHead ||
299+ ! state . renderedHtmlTag
300+ ) {
301+ let fallback : VNode = jsxTemplate ( [ html ] ) ;
302+ if ( ! state . renderedHtmlBody ) {
303+ let scripts : VNode | null = null ;
304+
305+ if (
306+ this . url . pathname !== this . config . basePath + DEV_ERROR_OVERLAY_URL
307+ ) {
308+ scripts = h ( FreshScripts , null ) as VNode ;
309+ }
310+
311+ fallback = h ( "body" , null , fallback , scripts ) ;
312+ }
313+ if ( ! state . renderedHtmlHead ) {
314+ fallback = h (
315+ Fragment ,
316+ null ,
317+ h ( "head" , null , h ( "meta" , { charset : "utf-8" } ) ) ,
318+ fallback ,
319+ ) ;
320+ }
321+ if ( ! state . renderedHtmlTag ) {
322+ fallback = h ( "html" , null , fallback ) ;
323+ }
324+
325+ html = renderToString ( fallback ) ;
326+ }
298327
299- return outer ;
328+ return `<!DOCTYPE html> ${ html } ` ;
300329 } catch ( err ) {
301330 if ( err instanceof Error ) {
302331 span . recordException ( err ) ;
0 commit comments