WIP! A BB-style forum, on the ATmosphere!
We're still working... we'll be back soon when we have something to show off!
node
typescript
hono
htmx
atproto
1import { Hono } from "hono";
2import { serve } from "@hono/node-server";
3import { serveStatic } from "@hono/node-server/serve-static";
4import { logger } from "hono/logger";
5import { existsSync } from "node:fs";
6import { resolve } from "node:path";
7import { webRoutes } from "./routes/index.js";
8import { loadConfig } from "./lib/config.js";
9
10const config = loadConfig();
11const app = new Hono();
12
13app.use("*", logger());
14
15const staticRoot = "./public";
16if (!existsSync(resolve(staticRoot))) {
17 console.error("CRITICAL: Static file directory not found", {
18 resolvedPath: resolve(staticRoot),
19 cwd: process.cwd(),
20 });
21}
22app.use("/static/*", serveStatic({ root: staticRoot }));
23app.route("/", webRoutes);
24
25app.onError((err, c) => {
26 console.error("Unhandled error in web route", {
27 path: c.req.path,
28 method: c.req.method,
29 error: err.message,
30 stack: err.stack,
31 });
32 const detail =
33 process.env.NODE_ENV !== "production"
34 ? `<p><code>${err.message}</code></p>`
35 : "";
36 return c.html(
37 `<!DOCTYPE html><html lang="en"><body><h1>Internal Server Error</h1><p>Something went wrong. Please try again later.</p>${detail}</body></html>`,
38 500
39 );
40});
41
42serve(
43 {
44 fetch: app.fetch,
45 port: config.port,
46 },
47 (info) => {
48 console.log(`atBB Web UI listening on http://localhost:${info.port}`);
49 }
50);