From c9735e934af2dc02b7dc38f0b8f21decf582348a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Gaudencio=20do=20R=C3=AAgo?= Date: Thu, 2 Jan 2025 17:19:55 -0300 Subject: [PATCH] Make preview SSR only --- runtime/fresh/plugin.tsx | 35 +++++++++++++++++++++++++++++++-- runtime/routes/blockPreview.tsx | 7 ++++++- runtime/routes/previews.tsx | 2 +- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/runtime/fresh/plugin.tsx b/runtime/fresh/plugin.tsx index 646bf6269..91b65f323 100644 --- a/runtime/fresh/plugin.tsx +++ b/runtime/fresh/plugin.tsx @@ -3,9 +3,11 @@ import type { AppManifest, SiteInfo } from "@deco/deco"; import { Deco, type PageData, type PageParams } from "@deco/deco"; import { framework as htmxFramework } from "@deco/deco/htmx"; -import type { ComponentType } from "preact"; +import type { ComponentChildren, ComponentType } from "preact"; import framework from "./Bindings.tsx"; import type { Plugin } from "$fresh/server.ts"; +import { renderToString } from "preact-render-to-string"; +import { HEAD_CONTEXT } from "$fresh/src/runtime/head.ts"; export type { Plugin } from "$fresh/server.ts"; export interface PluginRoute { @@ -65,12 +67,41 @@ export const component = ({ data }: PageParams) => { return ; }; +const adaptRenderOptions = ( + render: (data: unknown) => Promise | Response, +) => { + return (data: PageData) => { + if (data.page.props.options?.serverSideOnly) { + const headContextValue: ComponentChildren[] = []; + // Fill the headContextValue with from the page. + let res = renderToString( + + {data.page.Component(data.page.props)} + , + ); + // Render to string and add it to the head of the page. + const headContent = headContextValue.map((child) => { + try { + return renderToString(child); + } catch (error) { + console.error("Error rendering to string:", error); + return null; + } + }).filter((content) => content !== null).join(""); + res = + `${headContent}${res}`; + return new Response(res); + } + return render(data); + }; +}; + export function createFreshHandler( deco: Deco, ) { const h: PluginRoute["handler"] = (req: Request, ctx) => { return deco.handler(req, { - RENDER_FN: ctx.render.bind(ctx), + RENDER_FN: adaptRenderOptions(ctx.render.bind(ctx)), GLOBALS: ctx.state.global, }); }; diff --git a/runtime/routes/blockPreview.tsx b/runtime/routes/blockPreview.tsx index eb6187b29..e7b0b89d6 100644 --- a/runtime/routes/blockPreview.tsx +++ b/runtime/routes/blockPreview.tsx @@ -99,7 +99,12 @@ export const render = async ( return await ctx.render({ page: { Component: Preview, - props: { url: ctx.var.url, params: ctx.req.param(), data: page }, + props: { + url: ctx.var.url, + params: ctx.req.param(), + data: page, + options: { serverSideOnly: true }, + }, }, }); } finally { diff --git a/runtime/routes/previews.tsx b/runtime/routes/previews.tsx index 10981fd98..80c48d947 100644 --- a/runtime/routes/previews.tsx +++ b/runtime/routes/previews.tsx @@ -47,7 +47,7 @@ export const handler = createHandler((ctx) => { return ctx.render({ page: { Component: Preview, - props: {}, + props: { options: { serverSideOnly: true } }, }, }); });