Markdown to HTML Action

A GitHub Action that converts Markdown to HTML with Pandoc, using customizable templates and stylesheets.

Features

Live demos

View the demo gallery — the same Markdown rendered with each built-in theme:

Usage

Basic

name: Build Documentation
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Convert Markdown to HTML
        uses: CameronBrooks11/md2html-action@v1
        with:
          source-dir: "docs"
          output-dir: "website"

Single file

- name: Convert README to HTML
  uses: CameronBrooks11/md2html-action@v1
  with:
    source-file: "README.md"
    output-dir: "_site"
    template: "default"

In single-file mode the output is named after the input (README.mdREADME.html). For a Pages landing page at index.html, rename it after conversion, or use directory mode (which generates index.html from README.md automatically).

Deploy to GitHub Pages

name: Build and Deploy Docs
on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deploy.outputs.page_url }}
    steps:
      - uses: actions/checkout@v6

      - name: Convert Markdown to HTML
        id: convert
        uses: CameronBrooks11/md2html-action@v1
        with:
          source-dir: "docs"
          output-dir: "_site"
          site-title: "My Documentation"
          base-url: "https://USER.github.io/REPO"

      - uses: actions/upload-pages-artifact@v3
        with:
          path: ${{ steps.convert.outputs.output-path }}

      - id: deploy
        uses: actions/deploy-pages@v4

Inputs

Input Description Default
source-dir Directory of Markdown files to convert source
source-file Single Markdown file to convert (alternative to source-dir) | | `output-dir` | Directory where HTML files are generated | `_website` | | `template` | `default`, `minimal`, `github`, or a path to a template | `default` | | `stylesheet` | Built-in name, a local CSS path, or a remote URL | `default` | | `site-title` | Site title (navigation and meta tags) | `Documentation` | | `base-url` | Base URL for the site (useful for GitHub Pages) |
include-toc Include a table of contents true
pandoc-options Additional Pandoc command-line options ``

Outputs

Output Description
output-path Path to the generated HTML files
files-converted Number of files converted

Templates

Stylesheets

Built-in options (all responsive, with dark/light support where noted):

You can also pass a local file (assets/style.css) or a remote URL (https://.../style.css).

- uses: CameronBrooks11/md2html-action@v1
  with:
    source-dir: "docs"
    stylesheet: "technical"

Automatic behavior

A few things happen automatically, without configuration:

Markdown support

Standard Markdown plus tables, syntax-highlighted code blocks, footnotes, task lists, strikethrough, and math (MathJax). Frontmatter is optional; when present it can supply metadata:

---
title: "Custom Page Title"
description: "Page description for SEO"
author: "Your Name"
navbar_home: true
---
# Your content here

Custom templates

A template is an HTML file using Pandoc template variables. The most useful ones:

Variable Description
$title$ Page title
$body$ Converted Markdown content
$table-of-contents$ Table of contents (when enabled)
$site-title$ Site title from inputs
$rel_path$ Relative path to the site root
$stylesheet$ Local stylesheet path
$stylesheet-url$ Remote stylesheet URL
$base-url$ Base URL from inputs

See templates/default.html for a complete example.

Directory structure

your-repo/
├── docs/                  # Source Markdown
│   ├── index.md           # becomes index.html
│   ├── getting-started.md
│   ├── advanced/
│   │   └── configuration.md
│   └── media/             # images and other assets
└── .github/workflows/
    └── docs.yml           # your workflow

After conversion (output-dir: _website):

_website/
├── index.html
├── getting-started.html
├── advanced/
│   └── configuration.html
├── media/                 # copied assets
└── style.css              # stylesheet (for built-in/local stylesheets)

Requirements

Local testing

Run the workflows locally with act (requires Docker):

gh extension install https://github.com/nektos/gh-act

# run a single integration job, binding outputs into the working directory
gh act -j test-default-configuration --bind

# run all integration tests
gh act -W .github/workflows/integration-tests.yml --bind

With --bind, generated HTML is written to the corresponding outputs-* directory; serve any of them to preview, e.g. cd outputs-default-configuration && python -m http.server 8000.

Contributing

See CONTRIBUTING.md. In short: fork, branch, commit, and open a pull request.

License

MIT — see LICENSE.

Acknowledgments

Built with Pandoc.