A few simple helper functions to generate HTML from markdown. Just enough to get you started with markdown with Mastro.
By default, it uses micromark with micromark-extension-gfm under the hood.
Validate YAML frontmatter by bringing your own Standard Schema-compliant validation library (e.g. Zod, Valibot or validate.js).
The easiest way to get started is to install Mastro and select the "blog" template. Alternatively:
deno add jsr:@mastrojs/markdown
pnpm add jsr:@mastrojs/markdown
bunx jsr add @mastrojs/markdown
import { renderToString } from "@mastrojs";
import { markdownToHtml } from "@mastrojs/markdown";
const { content, meta } = await markdownToHtml(`
---
title: my title
---
hi *there*
`);
const htmlStr = await renderToString(content);In addition to markdownToHtml(inputStr, opts), there is:
readMarkdownFile(filePath, opts)readMarkdownFiles(globPattern, opts)serveMarkdownFolder(opts, renderFn)
For a tutorial, read the chapter A static blog from markdown files in the Mastro Guide.
The parse option can either take an options object, or a parse function. To supply a Micromark options object:
const { content, meta } = markdownToHtml(input, { parse: { allowDangerousHtml: true } });Micromark is fairly basic (e.g. no syntax highlighting of code blocks). If you want a more feature-rich markdown engine, supply a custom markdown-to-HTML function to parse, which will be called with the markdown body (YAML frontmatter already stripped).
For example using markdown-it:
import { markdownToHtml } from "@mastrojs/markdown";
import markdownIt from "markdown-it";
const { content, meta } = markdownToHtml(input, { parse: markdownIt.render });Or using remark-rehype:
import { markdownToHtml } from "@mastrojs/markdown";
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeHighlight from "rehype-highlight";
import rehypeStringify from "rehype-stringify";
const parse = async (markdownText: string) =>
String(
await unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeHighlight)
.use(rehypeStringify)
.process(markdownText)
);
const { content, meta } = markdownToHtml(input, { parse });The default TypeScript type for the YAML metadata is Record<string, unknown>. You can override that with e.g. readMarkdownFile<{title: string}>("post.md"). But to actually verify the metadata is correct, you should use a schema. For example using validate.js:
import { object, string } from "./validate.js";
const schema = object({
title: string,
});
const { content, meta } = await markdownToHtml(input, { schema }),