Themes

Themes control layout (HTML template), default MDX components, and optional theme pages/assets. The default theme in the Methanol repo is a good reference.

Theme Implementation Guide

Theme Shape

export default () => ({
	theme: {
		root: './theme',
		componentsDir: './components',
		pagesDir: './pages',
		publicDir: './public',
		sources: {
			'/theme': './sources'
		},
		template: ({ PageContent, ExtraHead, ctx, page, withBase, HTMLRenderer, components }) => (
			<>
				{HTMLRenderer.rawHTML`<!doctype html>`}
				<html lang="en">
					<head>
						<meta charset="UTF-8" />
						<meta name="viewport" content="width=device-width" />
						<ExtraHead />
						<title>{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>
		}
	}
})

Required

Defaults and Validation

Theme Layout Files

Suggested structure:

theme/
  index.js          # exports the theme object
  page.jsx          # template component
  components/       # default MDX components
  pages/            # optional theme pages
  public/           # optional public assets
  sources/          # assets mapped by theme.sources

Theme public/ is merged into the project publicDir during dev/build. If a path exists in both, the project asset wins.

Template Contract

theme.template receives:

Return a JSX tree.

Important: put <ExtraHead /> inside <head>. Without it, per-page <Head>/head and automatic page assets won’t be injected.

When your site is deployed under a subpath (site.base !== '/'):

Theme Components

theme.components provides default MDX components. User components in the project components/ override theme components by name.

The template also receives components, which is the merged result (useful for layout-level components like nav/search).

Theme Pages

Theme pages follow the same routing rules as user pages. User routes always override theme routes.

A theme-provided /404 is used only when the user project does not define its own 404 page.

Theme Public Assets

If the theme provides a publicDir, Methanol copies its files into the user public directory at dev/build start. When the user sets publicDir, theme files are still copied into it; files with the same name are skipped. If the user does not have a public directory, Methanol falls back to the theme public directory.

Theme Sources

theme.sources maps virtual URLs to files. This is handled by Methanol’s resolver (not Vite aliases).

export default () => ({
	theme: {
		root: './theme',
		sources: {
			'/theme': './sources'
		}
	}
})

Theme Hooks

A theme can also provide build hooks (same shape as user config hooks):