vt-ssg
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v73View latest version
A lightweight static site generator for Val Town. Takes a markdown string and a JSX layout template, returns an HTML string.
Stack: marked · gray-matter · Hono JSX
/** @jsxImportSource npm:hono@4/jsx */
import { render } from "https://esm.town/v/nbbaier/vt-ssg/main.tsx";
const html = await render({
markdown: `---
title: Hello World
date: 2026-04-04
---
# Hello
Some **markdown** content.`,
});
// html is a complete HTML string with <!DOCTYPE html>
Pass a Hono JSX component as the layout option. It receives title, content (rendered HTML), and the full frontmatter object as props.
/** @jsxImportSource npm:hono@4/jsx */
import { render } from "https://esm.town/v/nbbaier/vt-ssg/main.tsx";
import type { LayoutComponent } from "https://esm.town/v/nbbaier/vt-ssg/types.ts";
const BlogLayout: LayoutComponent = ({ title, content, frontmatter }) => (
<html lang="en">
<head>
<title>{title} | My Blog</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<header><nav>Home | About</nav></header>
<article>
<h1>{title}</h1>
<time>{String(frontmatter.date)}</time>
<div dangerouslySetInnerHTML={{ __html: content }} />
</article>
<footer>© 2026</footer>
</body>
</html>
);
const html = await render({
markdown: source,
layout: BlogLayout,
layoutProps: { theme: "dark" },
});
| Option | Type | Required | Description |
|---|---|---|---|
markdown | string | ✅ | Raw markdown string, optionally with YAML frontmatter |
layout | LayoutComponent | ❌ | Hono JSX component. Defaults to a minimal HTML shell. |
layoutProps | Record<string, unknown> | ❌ | Extra props merged into the layout props |
markedOptions | MarkedOptions | ❌ | Options passed to marked. GFM enabled by default. |
Props received by layout components:
| Prop | Type | Description |
|---|---|---|
title | string | Extracted from frontmatter.title, or "" |
content | string | Rendered HTML from the markdown body |
frontmatter | Record<string, unknown> | Full parsed frontmatter object |
...layoutProps | unknown | Any extra props passed via layoutProps |
Rendering mermaid diagram...
main.tsx — Public API: render() function
types.ts — TypeScript type definitions
frontmatter.ts — gray-matter wrapper
markdown.ts — marked wrapper
defaults.tsx — Default HTML layout component
test.tsx — Test script