GitHub GitHub
docs / Markdown

Markdown

LiteNode provides built-in methods for parsing Markdown files, extracting frontmatter, generating table of contents, and paginating content — making it a solid foundation for blogs, documentation sites, and content-driven apps.

Information LiteNode's methods return raw Markdown content. To convert it to HTML, use any parser you prefer — the examples below use Marked. See the full tutorial: Ultimate Markdown-Based Application in Node.js.

parseMarkdownFile

Signature:

parseMarkdownFile(filePath: string): Promise<{
    frontmatter: object
    content: string
    filePath: string
    fileDir: string
    fileName: string
    fileBaseName: string
}>

Parses a single Markdown file. File paths are relative to your template directory.

app.get("/post/:slug", async (req, res) => {
    const file = await app.parseMarkdownFile(`posts/${req.params.slug}.md`)
    const { frontmatter, content } = file
    const html = marked.parse(content)
    res.render("layouts/post.html", { title: frontmatter.title, html_content: html })
})

parseMarkdownFileS

Signature:

parseMarkdownFileS(dirPath: string): Promise<Array<{
    frontmatter: object
    content: string
    filePath: string
    fileDir: string
    fileName: string
    fileBaseName: string
}>>

Parses all Markdown files in a directory. Useful for blog listings, doc indexes, and sitemaps.

app.get("/blog", async (req, res) => {
    const posts = await app.parseMarkdownFileS("posts")
    posts.sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date))
    res.render("layouts/blog.html", { posts })
})

extractMarkdownProperties

Signature:

extractMarkdownProperties(
    files: ParsedFile[],
    properties: string[]
): Promise<object[]>

Extracts specific frontmatter properties from an array of parsed files. Useful for building navigation menus or index pages.

const pages = await app.parseMarkdownFileS("pages")
const nav = await app.extractMarkdownProperties(pages, ["title", "href"])
// → [{ title: "Usage", href: "usage" }, { title: "Routing", href: "routing" }, ...]

groupByMarkdownProperty

Signature:

groupByMarkdownProperty(
    dirPath: string,
    properties: string[],
    groupKey: string
): Promise<object>

Parses a directory and groups files by a frontmatter property.

app.get("/by-category", async (req, res) => {
    const grouped = await app.groupByMarkdownProperty("posts", ["title", "href", "category"], "category")
    res.json(grouped)
})

paginateMarkdownFiles

Signature:

paginateMarkdownFiles(
    input: string | ParsedFile[],
    page?: number,
    perPage?: number
): Promise<{
    page: number
    per_page: number
    prev_page: number | null
    next_page: number | null
    total_files: number
    total_pages: number
    data: object[]
}>

Paginates markdown files from a directory path or a pre-parsed array.

app.get("/blog", async (req, res) => {
    const page = parseInt(req.queryParams.get("page")) || 1
    const pagination = await app.paginateMarkdownFiles("posts", page, 10)
    res.render("layouts/blog.html", {
        posts: pagination.data,
        currentPage: pagination.page,
        totalPages: pagination.total_pages,
        prevPage: pagination.prev_page,
        nextPage: pagination.next_page,
    })
})

generateTOC

Signature:

generateTOC(input: string): string

Generates a nested HTML <ul> table of contents from heading elements (h2h6) in an HTML string. Headings must have id attributes — see Add IDs to Headings below.

const html = marked.parse(content)
const toc = app.generateTOC(html)
res.render("layouts/docs.html", { html_content: html, html_toc: toc })

Add IDs to Headings

generateTOC relies on heading id attributes. Many Markdown parsers (including Marked with extensions) generate them automatically. Alternatively, you can add them manually in your Markdown:

## My Section {#my-section}

The {#id} syntax is stripped from the rendered heading text and used as the element's id.


Custom Directory

All methods accept paths relative to the template directory. If you initialise LiteNode with a custom views directory, the same root applies:

const app = new LiteNode("public", "templates")
// Reads from templates/posts/...
const posts = await app.parseMarkdownFileS("posts")

See the Examples page for a complete blog and documentation setup.