Quick start Features Configuration Install Licensing GitHub Get started

Configuration

gomddoc runs with no configuration: point it at a folder and it serves README.md as the home page with the default theme. This page covers every setting for when you want to change that. The binary carries the same reference, so gomddoc info always matches the version you run.


Where settings come from

Each setting can come from four places. The highest one wins:

  1. Command-line flags and the positional directory argument
  2. GOMDDOC_* environment variables
  3. .gomddoc/config.yml in the content directory
  4. Built-in defaults

Settings fall into two groups:

dir_index and dev mode are the two exceptions to "highest wins": a flag can turn them on, but can't turn off a true set by the file or the environment.

When the content comes from a Git URL, a .gomddoc/config.yml inside the repository is ignored. Configure Git-sourced sites with environment variables. exclude, strip_extensions and theme.vars have no environment variable, so those sites run with their defaults.


The config file

.gomddoc/config.yml holds the site settings at the top level, with no site: wrapper. This example sets every key:

meta:
  title: My Project              # default: the directory name, title-cased
  description: Docs for My Project
  domain: docs.example.com       # bare host: no scheme, no path
  robots: ""                     # site-wide <meta name="robots">, e.g. noindex

default_index: README.md         # file served for a directory URL
dir_index: false                 # generated listing when a directory has no index
language: en-US                  # BCP 47 language of the root content
edit_url: https://github.com/my-org/my-repo/edit/main/docs

exclude:                         # glob patterns hidden from every route
  - drafts/
  - "*.bak"
strip_extensions: [.md]          # extensions removed from URLs

theme:
  name: default
  features:                      # all default to true
    mermaid: false
  vars:                          # emitted as --theme-<key> CSS properties
    primary: "#7c3aed"

highlighting:
  theme: github                  # any Chroma style name

search:
  index: true                    # build the full-text search index at startup

Every key is optional. gomddoc init writes a starter file with the common defaults filled in.

The loader is strict. An unknown key, a misplaced nesting level or a site: wrapper is a startup error that names the line, and so is a second YAML document after a --- separator. An empty or comment-only file means "use the defaults".

Site settings

Key Environment variable Default
meta.title GOMDDOC_SITE_META_TITLE Directory name, title-cased
meta.description GOMDDOC_SITE_META_DESCRIPTION empty
meta.domain GOMDDOC_SITE_META_DOMAIN empty
meta.robots GOMDDOC_SITE_META_ROBOTS empty
default_index GOMDDOC_SITE_DEFAULT_INDEX README.md
dir_index GOMDDOC_SITE_DIR_INDEX false
language GOMDDOC_SITE_LANGUAGE en-US
edit_url GOMDDOC_SITE_EDIT_URL empty
theme.name GOMDDOC_SITE_THEME_NAME default
theme.features.<k> GOMDDOC_SITE_THEME_FEATURES_<K> true
highlighting.theme GOMDDOC_SITE_HIGHLIGHTING_THEME github
search.index GOMDDOC_SITE_SEARCH_INDEX true
exclude none empty
strip_extensions none [.md]
theme.vars none empty

A few keys need more detail:


Excluding files

Dotfiles and dot-directories (.git/, .env, .gomddoc/) are never served, except .well-known/. exclude adds your own patterns:

exclude:
  - drafts/           # trailing slash: a directory and everything in it
  - "*.bak"           # no slash: matched against each path segment
  - internal/*.md     # with a slash: matched against the full path
  - TODO.md

Patterns use Go's path.Match syntax (*, ?, [abc]). An excluded file returns the same 404 as a missing one, under its clean URL too, and is left out of navigation, search, tags, the sitemap, the feed, MCP and build output. gomddoc doctor warns about a pattern that matches nothing, which is usually a typo.


Clean URLs

strip_extensions lists the extensions removed from URLs. With the default [.md], guide.md is served at /guide and /guide.md redirects there with a 301. Only rendered content is affected; images, CSS and JavaScript keep their extensions.

strip_extensions: [.md, .html]   # also serve guide.html at /guide
strip_extensions: []             # keep extensions in URLs

Each entry must start with a dot. When two files claim the same clean URL, such as guide.md and guide.html, the extension listed first wins and gomddoc doctor reports the collision. In a static build, stripped pages are written as guide/index.html, so clean URLs work on any static host.


Themes

Choosing a theme

theme:
  name: nord

Only default is bundled in the binary. The other seven (academic, gitbook, material, midnight, minimal, nord and ocean) come from gomddoc-themes: copy one into .gomddoc/assets/themes/<name>/ before selecting it. A theme that isn't installed falls back to default with a warning, and gomddoc doctor reports it.

Feature toggles

Features are optional parts of a theme. All default to on. Turn one off for the whole site:

theme:
  features:
    katex: false
    mermaid: false

Or with an environment variable, where the name after FEATURES_ is lowercased to form the key:

GOMDDOC_SITE_THEME_FEATURES_MERMAID=false gomddoc serve ./docs

The default theme reads these twelve:

Feature Controls
search Search button and Ctrl+K dialog
toc Table of contents and scroll highlighting
dark_mode Light/dark toggle
code_copy Copy button on code blocks
katex KaTeX math rendering
mermaid Mermaid diagrams
admonitions > [!NOTE] callouts; off, they render as plain quotes
heading_anchors Hover links on headings
color_chips Swatches next to hex codes in backticks
tag_chips Tag links at the top of the page
see_also Related pages at the end of the page
annotations Annotations button and notes on the page content

Other themes can read other keys. Every downloadable theme except minimal reads google_fonts, which stops it loading fonts from Google. Run gomddoc info to see the keys the active theme reads. Keys must match ^[a-z][a-z0-9_]*$.

A page can override any feature in its frontmatter, in either direction. Site defaults apply first, then the page's values:

---
features:
  katex: true
---

Theme variables

theme.vars becomes a :root block of CSS custom properties, one --theme-<key> per entry:

theme:
  vars:
    primary: "#2563eb"
    dark-primary: "#60a5fa"

The default theme reads primary, bg, text, dark-primary, dark-bg and dark-text. Keys may contain letters, digits and hyphens. A value containing {, }, ;, < or > is skipped with a warning.

Overriding templates

To change one piece of any theme, put a partial in .gomddoc/partials/. A file there, such as footer.html.tmpl, replaces the partial of the same name in whichever theme is active, and survives a change of theme.name.

For a full custom theme, create .gomddoc/assets/themes/<name>/layouts/default.html.tmpl. The default theme's partials stay available, so you only write what you change. Add layouts/error.html.tmpl for error pages, and any other layouts/<name>.html.tmpl becomes selectable with layout: <name> in frontmatter. Static files in .gomddoc/static/ are served under /_assets/.

Templates receive the site settings, the rendered page, its frontmatter, TOC, navigation tree, breadcrumbs, previous and next pages, and related pages. Helper functions include contentURL for internal links, canonicalURL, assetURL and inlineJSAsset / inlineCSSAsset / inlineHTMLAsset. The full list is in gomddoc help theming-and-assets.


Server settings

These are set by flag or environment variable only.

Environment variable Flag Default Purpose
GOMDDOC_SERVER_DIR positional <dir> . Content directory or Git URL
GOMDDOC_SERVER_PORT -p, --port :8080 Listen address; :auto takes the first free port from 8080
GOMDDOC_SERVER_ADMIN_PORT --admin-port empty Separate listener for metrics, pprof and health
GOMDDOC_SERVER_PPROF --pprof false Expose /debug/pprof/
GOMDDOC_SERVER_BASIC_AUTH_FILE --basic-auth-file empty htpasswd file, bcrypt hashes only
GOMDDOC_SERVER_GIT_SSH_KEY --git-key-file empty SSH private key for git+ssh:// sources
GOMDDOC_SERVER_GIT_STORAGE_DIR --git-storage-dir empty Clone to disk instead of memory
GOMDDOC_SERVER_DEV_MODE none false Dev mode for serve; always on in preview

A bare admin port such as :9090 binds 127.0.0.1. Give a host, such as 0.0.0.0:9090, to listen on other interfaces. Dev mode turns off template and asset caching, so theme edits show on refresh. There is no --dev flag.

HTTP tuning

Environment variable Default Maximum
GOMDDOC_SERVER_HTTP_READ_HEADER_TIMEOUT 5s 1m
GOMDDOC_SERVER_HTTP_WRITE_TIMEOUT 30s 5m
GOMDDOC_SERVER_HTTP_IDLE_TIMEOUT 2m 10m
GOMDDOC_SERVER_HTTP_MAX_HEADER_MB 1 10
GOMDDOC_SERVER_HTTP_SHUTDOWN_TIMEOUT 1s none

Durations use Go syntax (500ms, 45s, 2m). A zero, negative or out-of-range value in the first four falls back to the default with a warning. The shutdown timeout is the grace period for in-flight requests on SIGINT and SIGTERM; a negative value is an error and anything above 60s logs a warning.

Other environment variables

Variable Belongs to
GOMDDOC_DOMAIN --domain on serve, preview and build; overrides meta.domain
GOMDDOC_BUILD_OUTPUT build --output
GOMDDOC_PREVIEW_OPEN preview --open
GOMDDOC_DIR_INDEX preview --dir-index
SSH_KNOWN_HOSTS Known-hosts file for SSH Git sources; defaults to ~/.ssh/known_hosts

An empty variable counts as unset. A value that doesn't parse is ignored with a warning, and gomddoc doctor reports it along with any GOMDDOC_* variable gomddoc doesn't recognise.


Command flags

Every command takes -h / --help and --version. The directory argument defaults to . and accepts a Git URL everywhere except init, info and schema.

Command Flags
serve -p/--port (:8080), --admin-port, -d/--domain, --git-key-file, --git-storage-dir, --pprof, --basic-auth-file
preview -p/--port (:auto), -d/--domain, --open, --dir-index, --git-key-file, --git-storage-dir
build -o/--output (build/site), -d/--domain, --git-key-file, --git-storage-dir
mcp --git-key-file, --git-storage-dir
doctor --json, --strict, -v/--verbose, --git-key-file, --git-storage-dir
init -t/--theme (default)
info --json
schema none
help [topic] [section], -s/--search

preview always runs in dev mode and has no --admin-port, --pprof or --basic-auth-file. build refuses to write into a non-empty directory it didn't create, and replaces its own previous output. init fails if .gomddoc/config.yml already exists, and writes the theme name without installing the theme.


Frontmatter

Any page can start with a YAML block. These fields have built-in meaning:

---
title: Deployment Guide
description: Deploy the app with Docker and Kubernetes.
tags: [devops, docker]
date: 2026-01-15
author: Jane Doe
redirect_from:
  - /old/deploy
features:
  see_also: false
---
Field Effect
title Page title, navigation label, search results, Open Graph. Falls back to the first # heading, then the file name
description Meta description, Open Graph, Twitter card and search. Falls back to meta.description
tags Tag chips, /tags/ pages, "See also", tag: search, /api/tags and MCP find_related. Lowercased and trimmed
date YYYY-MM-DD or RFC 3339. JSON-LD datePublished, and the fallback date for the sitemap and feed
author Author in the page's JSON-LD
robots Per-page <meta name="robots">. noindex also drops the page from the sitemap and feed
og_type Open Graph type; defaults to article
lang The page's <html lang>, overriding language
layout Render with layouts/<name>.html.tmpl, falling back to default
redirect_from Old paths that 301 to this page in serve, and redirect pages in build
features Per-page feature toggles, merged over theme.features

Any other field is kept and available to templates as {{ index .Page.Meta "field" }}. gomddoc doctor reports special fields with the wrong type, such as tags: foo instead of a list, and a tag containing / or \ is dropped.


Checking your configuration

Four commands read the configuration from the binary itself, so they can't drift from the version you run:

gomddoc info ./docs                              # every setting, and whether config.yml loads
gomddoc doctor ./docs --strict                   # every problem with a fix; non-zero exit for CI
gomddoc schema > .gomddoc/config.schema.json     # JSON Schema for editor validation
gomddoc help configuration                       # the full configuration guide

info never fails on a broken config: it reports why the file didn't load and exits 0, which makes it the first thing to run after an edit. doctor exits 1 on any error, or on any warning with --strict. --json on either command prints the same document the MCP tools gomddoc_capabilities and gomddoc_doctor return.