export * from "https://deno.land/x/nano_jsx@v0.0.30/mod.ts"; import { Helmet, renderSSR as nanoRender, } from "https://deno.land/x/nano_jsx@v0.0.30/mod.ts"; import { setup } from "https://esm.sh/twind@0.16.16"; import { shim, virtualSheet, getStyleTag, TW, Configuration, VirtualSheet, } from "https://esm.sh/twind@0.16.16/shim/server"; import typography from "https://esm.sh/@twind/typography@0.0.2"; let SHEET_SINGLETON: VirtualSheet | null = null; function createSheet(twOptions = {}) { return SHEET_SINGLETON ??= setupSheet(twOptions); } // Setup TW sheet singleton function setupSheet(twOptions: Configuration) { const sheet = virtualSheet(); setup({ ...twOptions, sheet, plugins: { ...typography() } }); return sheet; } const html = ({ body, head, footer, styleTag }) => (`
${head} ${styleTag} ${body} ${footer.join("\n")} `); export interface SSRSettings { pathname?: string; clearState?: boolean; tw?: TW; } export function ssr(render: CallableFunction, options?: SSRSettings) { const sheet = createSheet(options?.tw ?? {}); sheet.reset(); const app = nanoRender(render(), options); shim(app, { tw: options?.tw }); const { body, head, footer } = Helmet.SSR(app); const styleTag = getStyleTag(sheet); return new Response( html({ body, head, footer, styleTag }), { headers: { "content-type": "text/html" } }, ); } export function memoizedSSR(render: CallableFunction, options?: SSRSettings) { let mresp: Response | null = null; return () => { const resp = mresp ?? (mresp = ssr(render, options)); return resp.clone(); }; }