Skip to content

Pezmc/simple-markdown-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple-markdown-builder

xkcd 927: Standards

Yet another markdown site generator (because Jekyll, Hugo, 11ty, Astro, Next.js, Gatsby, VitePress, Docusaurus, MkDocs, MkDocs Material, GitBook, Docus, VuePress, and Nuxt Content weren't enough)

A simple markdown-to-HTML site builder with optional translations.

Installation

bun add simple-markdown-builder

Usage

Basic Setup

import { build } from 'simple-markdown-builder'

await build({
  baseUrl: 'https://aerialyoga.example.com',
  templatePath: 'scripts/template.html',
  defaultMeta: {
    title: 'Aerial Yoga Studio',
    description: 'Aerial yoga classes and equipment',
    sidebarTitle: 'Aerial Yoga Studio',
    sidebarSummary: 'Welcome to our aerial yoga studio',
    backLinkHref: '/',
    backLinkLabel: 'Back to home',
  },
})

With Translations

import { build, ensureTranslations } from 'simple-markdown-builder'

const config = {
  baseUrl: 'https://aerialyoga.example.com',
  templatePath: 'scripts/template.html',
  defaultMeta: { /* ... */ },
  translations: {
    apiKey: process.env.DEEPL_API_KEY,
    targetLanguages: ['fr', 'nl'],
    defaultLang: 'en',
    supportedLangs: ['en', 'fr', 'nl'],
    customGlossary: {
      fr: {
        'aerial silks': 'soies aériennes',
      },
    },
  },
}

await ensureTranslations(config, 'content', false)
await build(config)

Development Server

import { startDevServer } from 'simple-markdown-builder'

await startDevServer(config, {
  port: 4173,
  outputDir: 'docs',
  clean: true, // Optional: clean HTML files before building
  refreshTranslations: false, // Optional: refresh translations on start
})

Configuration Options

  • contentDir - Source markdown directory (default: content)
  • outputDir - Output HTML directory (default: docs)
  • baseUrl - Base URL for absolute links (required)
  • defaultMeta - Default front matter values (required)
  • templatePath - Path to HTML template file (required)
  • homepageTemplatePath - Optional separate template for homepage
  • markdownOptions - MarkdownIt configuration options
  • translations - Translation config: false to disable, or object with DeepL settings
  • utmParams - UTM parameters object for external links
  • skipLinkCheck - Whether to skip link validation
  • clean - Clean HTML files from output directory before building (default: false)

Template Placeholders

Templates support these placeholders:

  • {{TITLE}} - Page title
  • {{DESCRIPTION}} - Page description
  • {{BODY}} - Rendered HTML body
  • {{LANGUAGE_SWITCHER}} - Language selector UI
  • {{LANG}} - Current page language code
  • {{BACK_LINK_HREF}} - Back link URL
  • {{BACK_LINK_LABEL}} - Back link text
  • {{SIDEBAR_TITLE}} - Sidebar title
  • {{SIDEBAR_SUMMARY}} - Sidebar summary
  • {{YEAR}} - Current year

Open Graph and Twitter Images

Images can be set in two ways:

  1. Default for all pages: Set in defaultMeta configuration
  2. Per-page: Set in the page's front-matter

ogImage: Used for Open Graph tags. If not provided, a warning is logged and the tag is omitted.

twitterImage: Used for Twitter Card image. Only set if explicitly provided (no fallback to ogImage).

Example:

await build({
  baseUrl: 'https://example.com',
  templatePath: 'template.html',
  defaultMeta: {
    title: 'My Site',
    description: 'Site description',
    ogImage: 'img/default-og.png', // Default for all pages
    twitterImage: 'img/default-twitter.png', // Optional
    // ... other meta fields
  },
})

Or per-page in front-matter:

---
title: My Page
ogImage: img/page-specific-og.png
twitterImage: img/page-specific-twitter.png
---

Breaking Changes in v1.0

Template Placeholders Removed: The following placeholders are no longer needed - meta tags are automatically injected:

  • {{OG_URL}}, {{OG_TITLE}}, {{OG_DESCRIPTION}}, {{OG_IMAGE}}
  • {{TWITTER_TITLE}}, {{TWITTER_DESCRIPTION}}, {{TWITTER_IMAGE}}
  • {{CANONICAL_URL}}, {{HREFLANG_LINKS}}, {{NOINDEX}}, {{META_TAGS}}

Note: {{DESCRIPTION}} is still available as a template placeholder for use in the body content, but the meta description tag is automatically injected in the head.

Migration: Remove these placeholders from your templates. Ensure your template has a </head> tag - all meta tags will be automatically injected before it.

UTM Parameters

UTM parameters are provided as an object:

{
  utmParams: {
    utm_campaign: 'mycampaign',
    utm_medium: 'website',
    utm_source: 'mysite',
  },
}

These are automatically appended to external links.

Slugs and File Paths

Slugs default to the filename (without extension). Directory structure is automatically preserved in the output:

  • content/index.mddocs/index.html
  • content/about.mddocs/about.html
  • content/classes/beginner.mddocs/classes/beginner.html

You can override the slug in front matter if needed:

---
title: About Us
slug: about
---

If the slug contains a path (e.g., slug: shop/aerial-silks), it will be used directly for the output path.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors