Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
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
74
75
76
77
78
79
// static / vanilla js version of jxnblkio
/** @jsxImportSource https://esm.sh/react */
import { match } from "https://esm.sh/path-to-regexp";
import { MdContrast } from "https://esm.sh/react-icons/md";
import React from "https://esm.sh/react@18.3.1";
import { useMemo, useState } from "https://esm.sh/react@18.3.1";
import { analytics } from "https://esm.town/v/jxnblk/analytics";
import { Avatar } from "https://esm.town/v/jxnblk/avatar";
import { App, Route } from "https://esm.town/v/jxnblk/JxnblkApp";
import { colors, css } from "https://esm.town/v/jxnblk/JxnblkCSS";
import { DataRequest, render, robots } from "https://esm.town/v/jxnblk/ReactStream";
import redirects from "https://esm.town/v/jxnblk/redirects";
import { rss } from "https://esm.town/v/jxnblk/rss";
import data from "https://blog.jxnblk.com/api/all.json?d4" with { type: "json" };
interface Params {
slug?: string;
}
type AppCookies = {
color?: number;
};
export default render(App, false, [
analytics,
robots("User-agent: *\nAllow: /"),
redirects,
rss(data),
getInitialProps,
cacheHeaders,
]);
const matches = {
home: match("/"),
blog: match("/blog"),
post: match("/blog/:slug"),
};
async function getInitialProps(req: DataRequest, res: Response, next): Promise<Response> {
let params: Params = {};
let route: Route = Route.Home;
if (matches.post(req.data.pathname)) {
params.slug = matches.post(req.data.pathname).params.slug;
data.post = data.posts?.find(p => p.slug === params.slug);
route = Route.Post;
} else if (matches.blog(req.data.url.pathname)) {
route = Route.Blog;
} else if (!matches.home(req.data.pathname)) {
route = Route.Unknown;
}
const { about, posts, post } = data;
const size = JSON.stringify(posts).length;
req.data.data = {
posts: posts.filter(p => !p.draft),
post,
about,
params,
route,
size,
vanilla: true,
};
if (route === Route.Unknown) {
res = new Response(null, {
status: 404,
headers: res.headers,
});
console.log("404", res);
return next(res);
}
return next();
}
async function cacheHeaders(req: DataRequest, res: Response, next): Promise<Response> {
res.headers.set("Cache-Control", "max-age=31536000");
return next();
}