69 name: `${projectDetails.name}_${Date.now().toString()}`,
70 description: projectDetails.description ?? undefined,
71 imageUrl: projectDetails.imageUrl ?? undefined,
72 });
73 console.log("New project created:", newProject);
6 <title>React Hono Val Town Starter</title>
7 <script src="https://cdn.tailwindcss.com"></script>
8 <link rel="icon" href="/public/favicon.svg" sizes="any" type="image/svg+xml">
9 </head>
10 <body>
69 name: `${projectDetails.name}_${Date.now().toString()}`,
70 description: projectDetails.description ?? undefined,
71 imageUrl: projectDetails.imageUrl ?? undefined,
72 });
73 console.log("New project created:", newProject);
3 <source media="(prefers-color-scheme: dark)" srcset="https://mintlify.s3.us-west-1.amazonaws.com/autoblocks/logo/dark.png">
4 <source media="(prefers-color-scheme: light)" srcset="https://mintlify.s3.us-west-1.amazonaws.com/autoblocks/logo/light.png">
5 <img alt="Autoblocks Logo" width="300px" src="https://app.autoblocks.ai/images/logo-black.png">
6 </picture>
7</p>
30 - **`proxy.ts`**: Proxy to the old blog for legacy content
31 - **`rss.ts`**: RSS feed generation
32 - **`favicon.ts`** & **`og-image.ts`**: Asset routes
33- **`/utils/`**: Utility functions for post processing, caching, etc.
34- **`/posts/`**: Markdown files for blog posts
69- Tables
70- Lists
71- Images
72- And other standard markdown features
73
91- Efficient proxy for legacy content
92- Minimal CSS with no external frameworks
93- Optimized image handling
94
95## Deployment
4const LINE_HEIGHT = 72;
5
6export default function OGImage({
7 title = "Val Town Blog",
8 ...props
3import { Hono } from "https://esm.sh/hono@3.12.0";
4import { renderToStaticMarkup } from "https://esm.sh/react-dom@18.2.0/server";
5import OGImage from "../components/OGImage.tsx";
6
7const app = new Hono();
10 const title = c.req.query("title");
11 const format = c.req.query("format");
12 const svg = renderToStaticMarkup(<OGImage title={title} />);
13
14 if (format === "svg") {
15 return new Response(svg, {
16 headers: {
17 "Content-Type": "image/svg+xml",
18 },
19 });
24 return new Response(png, {
25 headers: {
26 "Content-Type": "image/png",
27 "Content-Length": png.length.toString(),
28 },
3import faviconRoute from "./routes/favicon.ts";
4import homeRoutes from "./routes/home.ts";
5import ogImageRoute from "./routes/og-image.ts";
6import proxyRoutes from "./routes/proxy.ts";
7import rssRoute from "./routes/rss.ts";
23app.route("/rss.xml", rssRoute);
24app.route("/favicon.svg", faviconRoute);
25app.route("/og-image.png", ogImageRoute);
26app.route("/", blogRoutes);
27
1Eventually we should host all our images properly, but for now, drag and drop them here 👇
2
3* https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/4d90a6f7-247c-4df4-3de6-928364e10000/public
4* https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/f175100b-a190-4772-7056-04c09f273a00/public
12}) {
13 const description = post?.description ?? SITE_DESCRIPTION;
14 const ogImage = new URL("/og-image.png", BLOG_URL);
15 ogImage.searchParams.append("title", title);
16
17 return (
19 <meta charSet="UTF-8" />
20 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21 <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
22
23 <title>{title === "Val Town Blog" ? title : `${title} | Val Town Blog`}</title>
30 <meta property="og:description" content={description} />
31
32 <meta property="og:image" content={ogImage} />
33
34 {/* Twitter */}
35 <meta property="twitter:card" content="summary_large_image" />
36 <meta property="twitter:url" content={BLOG_URL} />
37 <meta property="twitter:title" content={title} />
38 <meta property="twitter:description" content={description} />
39
40 <meta property="twitter:image" content={ogImage} />
41
42 {