Configuration

Methanol reads configuration from:

methanol.config.{js,mjs,cjs,ts,jsx,tsx,mts,cts}

If no config is present, Methanol uses defaults based on the current directory.

Config Shape

The config file must export a function. The function receives a context object and returns a config object.

export default ({ mode, root, HTMLRenderer }) => ({
	// config values
})

Context fields:

Core Options

root

Project root. Defaults to the current working directory.

site

Site metadata used by templates:

Notes:

pagefind

Enable or configure Pagefind search. Default: false.

pagefind: false
// or
pagefind: { enabled: true }
// or
pagefind: {
	enabled: true,
	excerptLength: 30,
	build: {
		outputSubdir: 'pagefind',
		verbose: true
	}
}

Notes:

starryNight

Controls code highlighting (rehype-starry-night). Default: false.

starryNight: false
// or
starryNight: true
// or
starryNight: {
	// options forwarded to rehype-starry-night
}

gfm

Enable or disable GitHub Flavored Markdown (GFM). Default: true.

When enabled, Methanol applies GFM parsing (tables, task lists, strikethrough, footnotes, autolink literals).

gfm: true
// or
gfm: false

pagesDir

Where MDX/MD files live (routes). Default: pages with a fallback to docs if pages/ does not exist.

componentsDir

Where JSX/TSX components live. Default: components.

If you explicitly set pagesDir or componentsDir (including via CLI), Methanol throws if the directory does not exist.

publicDir

Static assets folder served at the site root (e.g. public/foo.png/foo.png). Default: public.

Methanol also includes theme public assets (theme.publicDir). When both theme and user assets exist, Methanol merges them into a single directory (theme first, then user), so user assets override theme assets on path conflicts.

When merging is needed, the internal merged directory is created under node_modules/.methanol/assets (or {pagesDir}/.methanol/assets if node_modules/ does not exist).

Set publicDir: false to disable public assets entirely (including theme assets).

distDir

Output folder for production builds. Default: dist.

buildDir

Intermediate build directory (used with emitIntermediate). Default: build.

intermediateDir

Explicit directory to write intermediate HTML output (build only).

emitIntermediate

Boolean. When true, Methanol writes intermediate HTML to build/ during build.

theme

Theme configuration. See Advanced themes for full usage.

Key fields:

mdx

Customize MDX compilation. This function receives { mode, root } and should return MDX options.

vite

Merge custom Vite config. This function receives { command, mode, root, isPreview }.

preBuild / preBundle / postBundle / postBuild

Hooks for customizing the build pipeline.

Hook context:

Bundle/post-build hooks also receive:

Example:

export default () => ({
	preBuild: ({ data, site }) => {
		data.startedAt = Date.now()
		console.log('Building', site.name)
	},
	preBundle: ({ pages }) => {
		console.log('Rendered pages:', pages.length)
	},
	postBuild: ({ data, pages }) => {
		console.log('Duration (ms):', Date.now() - data.startedAt)
		console.log('Pages:', pages.length)
	}
})

CLI Overrides

Command line options override config values:

Example

import tailwindcss from '@tailwindcss/vite'

export default ({ mode }) => ({
	site: { name: 'My Docs' },
	theme: {
		root: '.',
		template: ({ PageContent, ExtraHead, ctx, withBase, HTMLRenderer, components }) => (
			<>
				{HTMLRenderer.rawHTML`<!doctype html>`}
				<html lang="en">
					<head>
						<meta charset="UTF-8" />
						<meta name="viewport" content="width=device-width" />
						<ExtraHead />
						<title>{ctx.page.title || ctx.site.name}</title>
						<link rel="icon" href="/favicon.png" />
					</head>
					<body>
						{components.Callout ? <components.Callout>Hi</components.Callout> : null}
						<PageContent />
					</body>
				</html>
			</>
		),
		components: {
			Callout: ({ children }) => <div class="callout">{children}</div>
		}
	},
	mdx: () => ({
		development: mode !== 'production'
	}),
	vite: () => ({
		server: { port: 5173 },
		plugins: [tailwindcss()]
	})
})