Configuration
Methanol automatically resolves configuration from the following file patterns:
methanol.config.{js,mjs,cjs,ts,jsx,tsx,mts,cts}
In the absence of a configuration file, Methanol applies sensible defaults inferred from the project's root directory.
Configuration Schema
The configuration file must export a function that receives an execution context and returns a configuration object.
export default ({ mode, root, HTMLRenderer }) => ({
// configuration properties
})
Execution context properties:
mode: Eitherdevelopmentorproduction.root: The absolute path to the project root.HTMLRenderer: rEFui HTML utilities (includingrawHTMLandserialize).
Core Options
root
The project root directory. Defaults to the current working directory (CWD).
site
Site-wide metadata utilized by templates:
site.name: The title of the site.site.owner: The site owner or author (used in the blog theme footer and feeds).site.logo: Path to the logo asset (string), orfalseto disable (standard theme support).site.favicon: Path to the favicon asset (string), orfalseto disable (standard theme support).site.base: The Base Path prefix used when the site is hosted under a subpath (e.g.,'/docs/').site.repoBase: The base URL for the content directory within a repository, used by the standard theme to generate "Edit this page" links.
Notes:
site.baseis automatically normalized to include both leading and trailing slashes (e.g.,docsbecomes'/docs/').site.baseserves as the default Vitebaseunlessvite.baseis explicitly defined.- In
devmode (methanol dev),site.baseis ignored and treated as/to ensure module resolution consistency. Verify subpath deployments using thebuildandserveworkflow.
pagefind
Enables and configures full-text search via Pagefind. Default: false.
pagefind: false
// or
pagefind: { enabled: true }
// or detailed configuration
pagefind: {
enabled: true,
excerptLength: 30,
build: {
outputSubdir: 'pagefind',
verbose: true
}
}
Notes:
- Properties other than
enabledandbuildare passed directly to the Pagefind JavaScriptoptions()initialization. - The
buildobject contains options specific to the build-time indexing process.
feed
Enables RSS/Atom feed generation. Default: false.
feed: true
// or
feed: {
enabled: true,
path: '/rss.xml',
limit: 10,
siteUrl: 'https://example.com',
title: 'My Site',
description: 'Updates from my site',
language: 'en',
atom: false
}
Notes:
- Use
atom: trueto output Atom instead of RSS (default paths:/rss.xmlor/atom.xml). siteUrlmust be an absolute URL. If omitted, Methanol usessite.base, so set it to a full origin (e.g.https://example.com/).- Hidden pages are excluded.
limitdefaults to10. - Feed items use
frontmatter.authorwhen provided, falling back tosite.owner.
pwa
Enables Methanol's built-in PWA support, featuring a custom service worker and an automated precache manifest. Default: false.
pwa: true
// or
pwa: false
// or detailed configuration
pwa: {
manifest: {
name: 'My Site',
short_name: 'My Site'
},
precache: {
include: ['**/*.{html,js,css,ico,png,svg,webp,jpg,jpeg,gif,woff,woff2,ttf}'],
exclude: ['**/*.map', '**/pagefind/**'],
priority: null,
limit: null,
batchSize: null
}
}
Notes:
manifestis merged into the generatedmanifest.webmanifest.precacheconfiguration governsprecache-manifest.json, used by the built-in service worker for installation and warming.precache.priority: Ordered list of glob patterns to cache immediately.precache.limit: Maximum number of entries in the precache manifest (nullfor unlimited).precache.batchSize: Number of concurrent fetches during installation/warmup.- To fully customize PWA behavior, set
pwa: falseand provide your own manifest and service worker.
starryNight
Controls syntax highlighting via Starry Night (rehype-starry-night). Default: true.
starryNight: false
// or
starryNight: true
// or detailed configuration
starryNight: {
// options passed to rehype-starry-night
}
- When configured as an object, highlighting is enabled unless
enabled: falseis explicitly set. - Per-page Frontmatter settings always take precedence over global configuration.
- The CLI flags
--highlightand--no-highlightcan be used to override this setting per-execution. - Methanol automatically loads grammars for fenced code languages it encounters. Use
starryNight.grammarsonly to force ambiguous mappings or to supply unsupported grammars.
jobs
Controls the worker thread count used during the build pipeline. Default: 0 (auto based on page count).
jobs: 0 // auto (round(ln(pageCount))), clamped to CPU cores
// or
jobs: 4
- The CLI flag
--jobs(alias-j) overrides this setting per-execution.
gfm
Enables or disables GitHub Flavored Markdown (GFM) support. Default: true.
When enabled, Methanol applies GFM-specific parsing, including tables, task lists, strikethrough, footnotes, and autolink literals.
gfm: true
// or
gfm: false
pagesDir
The source directory for MDX and Markdown files. Defaults to pages, with an automatic fallback to docs if pages/ is not found.
componentsDir
The directory for JSX/TSX components. Defaults to components.
If pagesDir or componentsDir are explicitly defined (via configuration or CLI) but do not exist, Methanol will throw an error.
publicDir
The directory for static assets served at the site root (e.g., public/foo.png maps to /foo.png). Default: public.
Methanol automatically merges assets from the theme's publicDir. In the event of a path conflict, user-provided assets override theme assets.
Temporary merged assets are managed within node_modules/.methanol/assets (or {pagesDir}/.methanol/assets if node_modules/ is unavailable).
Set publicDir: false to disable all static asset processing.
distDir
The destination directory for production builds. Default: dist.
buildDir
The directory for intermediate build artifacts. Default: build.
intermediateDir
Explicit directory for intermediate HTML output (build only).
emitIntermediate
Boolean. If true, Methanol writes intermediate HTML to the build/ directory during the build process.
theme
Configures the site's theme. This can be a theme object (see below) or a string. When a string is provided, Methanol resolves it using the following priority:
- Built-in Themes: Matches against Methanol's internal themes (e.g.,
default,blog). - Package Resolution: Searches for a package named
methanol-theme-xxx(wherexxxis your input).
For local themes (files inside your project), import them in methanol.config.* and set theme to the imported theme object/factory.
Refer to the Advanced Theme Guide for complete specifications of the theme object.
theme.root: The theme's root directory (required).theme.template: The JSX function defining the HTML layout.theme.components: Default components provided by the theme.theme.componentsDir: Directory for theme-specific components.theme.pagesDir: Directory for theme-provided pages.theme.publicDir: Theme static assets (merged intopublicDir).theme.sources: Virtual path mappings resolved by Methanol.theme.mdx: Default MDX options merged with user settings.theme.vite: Default Vite configuration merged with user settings.
mdx
Customizes the MDX compilation process. Receives { mode, root } and returns an MDX options object.
vite
Merges custom Vite configurations. Receives { command, mode, root, isPreview }.
preBuild / preBundle / postBundle / postBuild
Hooks for extending the build pipeline.
preBuild: Executes at dev server initialization and prior to the build process.preBundle: Build only; executes after page rendering but before Vite asset bundling.postBundle: Build only; executes after Vite bundling but before Pagefind indexing.postBuild: Build only; executes after the entire build process is complete.- Hooks accept either a single function or an array of functions.
- Execution sequence: User
preBuild→ ThemepreBuild→ Render → UserpreBundle→ ThemepreBundle→ Bundle → ThemepostBundle→ UserpostBundle→ (Optional) Pagefind → ThemepostBuild→ UserpostBuild.
Hook Context:
mode,root,command,isDev,isBuild,isPreview.HTMLRenderer.site(reflects the currentctx.sitestate).data: A mutable object for sharing state across the hook lifecycle.
preBundle, postBundle, and postBuild hooks additionally receive:
pagesContext,pages,pagesTree, andpagesByRoute.
Example:
export default () => ({
preBuild: ({ data, site }) => {
data.startedAt = Date.now()
console.log('Building:', site.name)
},
preBundle: ({ pages }) => {
console.log('Total rendered pages:', pages.length)
},
postBuild: ({ data, pages }) => {
console.log('Build duration (ms):', Date.now() - data.startedAt)
console.log('Final page count:', pages.length)
}
})
CLI Overrides
Command-line arguments take precedence over configuration file settings:
--inputand--componentsoverridepagesDirandcomponentsDir.--assetsoverridespublicDir.--outputoverridesdistDir.--site-nameoverridessite.name.--owneroverridessite.owner.--basetemporarily overridessite.base(ignored indev).--search/--no-searchoverridepagefind.enabled.--rss/--no-rssoverridefeed.enabled.--atom/--no-atomoverridefeed.atom.--pwa/--no-pwaoverride thepwatoggle.-v/--verboseenables detailed build logging.--configspecifies a non-standard configuration file.- Positional
input/outputarguments map to the--input/--outputflags.
Implementation Example
import tailwindcss from '@tailwindcss/vite'
export default ({ mode }) => ({
site: { name: 'Technical 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>Important Note</components.Callout> : null}
<PageContent />
</body>
</html>
</>
),
components: {
Callout: ({ children }) => <div class="callout-component">{children}</div>
}
},
mdx: () => ({
development: mode !== 'production'
}),
vite: () => ({
server: { port: 5173 },
plugins: [tailwindcss()]
})
})