Readme

Example Make a web app on val.town with server-side rendered Preact components

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
export const preactWebApp = (function () {
type propType =
& {
setHeaders: (headers: {
[key: string]: string | string[];
}) => void;
setStatus: (status: number) => void;
req: express.Request;
html: (
strings: TemplateStringsArray,
...values: any[]
) =>
| import("npm:preact@10.17.0").VNode<
import("npm:preact@10.17.0").Attributes
>
| import("npm:preact@10.17.0").VNode<
import("npm:preact@10.17.0").Attributes
>[];
}
& typeof import("npm:preact@10.17.0")
& typeof import("npm:preact@10.17.0/hooks");
const preactWebApp =
(App: (_: propType) => import("npm:preact@10.17.0").VNode) =>
async (req: express.Request, res: express.Response) => {
const preact = await import("npm:preact@10.17.0");
const hooks = await import("npm:preact@10.17.0/hooks");
const _renderToString = await import("npm:preact-render-to-string@6.2.1");
const { renderToString } = _renderToString;
const { default: htm } = await import("npm:htm@3.1.1");
const html = htm.bind(preact.h);
try {
let status = 200;
let headers: {
[key: string]: string | string[];
} = {};
const props: propType = {
html,
req,
setStatus: (s: number) => {
status = s;
},
setHeaders: (h: typeof headers) => {
headers = h;
},
...preact,
...hooks,
};
const renderedHtml = "<!DOCTYPE html>" +
renderToString(await App(props));
for (const [k, v] of Object.entries(headers))
res.set(k, v);
res.status(status);
res.send(renderedHtml);
}
catch (e) {
const etext = e.stack || JSON.stringify(e);
console.error(etext);
res.status(500);
res.send(renderToString(preact.h(
"html",
null,
html`
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>html{font-family:sans-serif;color-scheme:dark light;padding:1rem}h1{font-size:2.5rem;font-weight:300;margin:1rem 0}pre{overflow-x:auto;color:GrayText;white-space:pre-wrap;word-wrap:break-word}</style>
<h1>error running val</h1>
<pre>${etext}</pre>
`,
)));
}
};
preactWebApp.props = {} as propType;
return preactWebApp;
}).call(this);
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.