]> Untitled Git - lemmy-ui.git/blob - src/server/utils/create-ssr-html.tsx
Merge branch 'main' into expand-video-embeds-to-fullwidth
[lemmy-ui.git] / src / server / utils / create-ssr-html.tsx
1 import { Helmet } from "inferno-helmet";
2 import { renderToString } from "inferno-server";
3 import serialize from "serialize-javascript";
4 import sharp from "sharp";
5 import { ILemmyConfig, IsoDataOptionalSite } from "../../shared/interfaces";
6 import { favIconPngUrl, favIconUrl } from "../../shared/utils";
7 import { fetchIconPng } from "./fetch-icon-png";
8 import { generateManifestBase64 } from "./generate-manifest-base64";
9
10 const customHtmlHeader = process.env["LEMMY_UI_CUSTOM_HTML_HEADER"] || "";
11
12 export async function createSsrHtml(
13   root: string,
14   isoData: IsoDataOptionalSite
15 ) {
16   const site = isoData.site_res;
17
18   const appleTouchIcon = site?.site_view.site.icon
19     ? `data:image/png;base64,${sharp(
20         await fetchIconPng(site.site_view.site.icon)
21       )
22         .resize(180, 180)
23         .extend({
24           bottom: 20,
25           top: 20,
26           left: 20,
27           right: 20,
28           background: "#222222",
29         })
30         .png()
31         .toBuffer()
32         .then(buf => buf.toString("base64"))}`
33     : favIconPngUrl;
34
35   const erudaStr =
36     process.env["LEMMY_UI_DEBUG"] === "true"
37       ? renderToString(
38           <>
39             <script src="//cdn.jsdelivr.net/npm/eruda"></script>
40             <script>eruda.init();</script>
41           </>
42         )
43       : "";
44
45   const helmet = Helmet.renderStatic();
46
47   const config: ILemmyConfig = { wsHost: process.env.LEMMY_UI_LEMMY_WS_HOST };
48
49   return `
50     <!DOCTYPE html>
51     <html ${helmet.htmlAttributes.toString()}>
52     <head>
53     <script>window.isoData = ${serialize(isoData)}</script>
54     <script>window.lemmyConfig = ${serialize(config)}</script>
55   
56     <!-- A remote debugging utility for mobile -->
57     ${erudaStr}
58   
59     <!-- Custom injected script -->
60     ${customHtmlHeader}
61   
62     ${helmet.title.toString()}
63     ${helmet.meta.toString()}
64   
65     <!-- Required meta tags -->
66     <meta name="Description" content="Lemmy">
67     <meta charset="utf-8">
68     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
69     <link
70        id="favicon"
71        rel="shortcut icon"
72        type="image/x-icon"
73        href=${site?.site_view.site.icon ?? favIconUrl}
74      />
75   
76     <!-- Web app manifest -->
77     ${
78       site &&
79       `<link
80           rel="manifest"
81           href=${`data:application/manifest+json;base64,${await generateManifestBase64(
82             site
83           )}`}
84         />`
85     }
86     <link rel="apple-touch-icon" href=${appleTouchIcon} />
87     <link rel="apple-touch-startup-image" href=${appleTouchIcon} />
88   
89     <!-- Styles -->
90     <link rel="stylesheet" type="text/css" href="/static/styles/styles.css" />
91   
92     <!-- Current theme and more -->
93     ${helmet.link.toString()}
94     
95     </head>
96   
97     <body ${helmet.bodyAttributes.toString()}>
98       <noscript>
99         <div class="alert alert-danger rounded-0" role="alert">
100           <b>Javascript is disabled. Actions will not work.</b>
101         </div>
102       </noscript>
103   
104       <div id='root'>${root}</div>
105       <script defer src='/static/js/client.js'></script>
106     </body>
107   </html>
108   `;
109 }