1 import { getStaticDir } from "@utils/env";
2 import { Helmet } from "inferno-helmet";
3 import { renderToString } from "inferno-server";
4 import serialize from "serialize-javascript";
5 import sharp from "sharp";
6 import { favIconPngUrl, favIconUrl } from "../../shared/config";
7 import { IsoDataOptionalSite } from "../../shared/interfaces";
8 import { buildThemeList } from "./build-themes-list";
9 import { fetchIconPng } from "./fetch-icon-png";
11 const customHtmlHeader = process.env["LEMMY_UI_CUSTOM_HTML_HEADER"] || "";
13 let appleTouchIcon: string | undefined = undefined;
15 export async function createSsrHtml(
17 isoData: IsoDataOptionalSite,
20 const site = isoData.site_res;
22 const fallbackTheme = `<link rel="stylesheet" type="text/css" href="/css/themes/${
23 (await buildThemeList())[0]
26 const customHtmlHeaderScriptTag = new RegExp("<script", "g");
27 const customHtmlHeaderWithNonce = customHtmlHeader.replace(
28 customHtmlHeaderScriptTag,
29 `<script nonce="${cspNonce}"`,
32 if (!appleTouchIcon) {
33 appleTouchIcon = site?.site_view.site.icon
34 ? `data:image/png;base64,${await sharp(
35 await fetchIconPng(site.site_view.site.icon),
43 background: "#222222",
47 .then(buf => buf.toString("base64"))}`
52 process.env["LEMMY_UI_DEBUG"] === "true"
57 src="//cdn.jsdelivr.net/npm/eruda"
59 <script nonce={cspNonce}>eruda.init();</script>
64 const helmet = Helmet.renderStatic();
68 <html ${helmet.htmlAttributes.toString()}>
70 <script nonce="${cspNonce}">window.isoData = ${serialize(isoData)}</script>
72 <!-- A remote debugging utility for mobile -->
75 <!-- Custom injected script -->
76 ${customHtmlHeaderWithNonce}
78 ${helmet.title.toString()}
79 ${helmet.meta.toString()}
81 <!-- Required meta tags -->
82 <meta name="Description" content="Lemmy">
83 <meta charset="utf-8">
84 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
89 href=${site?.site_view.site.icon ?? favIconUrl}
92 <!-- Web app manifest -->
93 <link rel="manifest" href="/manifest.webmanifest" />
94 <link rel="apple-touch-icon" href=${appleTouchIcon} />
95 <link rel="apple-touch-startup-image" href=${appleTouchIcon} />
98 <link rel="stylesheet" type="text/css" href="${getStaticDir()}/styles/styles.css" />
100 <!-- Current theme and more -->
101 ${helmet.link.toString() || fallbackTheme}
105 <body ${helmet.bodyAttributes.toString()}>
107 <div class="alert alert-danger rounded-0" role="alert">
108 <b>Javascript is disabled. Actions will not work.</b>
112 <div id='root'>${root}</div>
113 <script defer src='${getStaticDir()}/js/client.js'></script>