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 rather than Rsbuild aliases.

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

Theme Hooks

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