How to Use Docusaurus Preset Configurations: Complete Guide with Examples
Docusaurus preset configurations are reusable bundles that combine plugins, themes, and default options into a single configuration entry, allowing you to initialize a complete documentation site by referencing one preset name instead of manually wiring individual components.
When building documentation sites with the facebook/docusaurus framework, you typically need to register multiple plugins and themes to handle content, navigation, and styling. Docusaurus preset configurations streamline this process by packaging these elements into composable units that the core server expands automatically during the build pipeline.
What Are Docusaurus Preset Configurations?
Presets are higher-level abstractions that aggregate related plugins, themes, and default site options into a single importable function. Rather than listing @docusaurus/plugin-content-docs, @docusaurus/plugin-content-blog, and @docusaurus/theme-classic separately in your configuration file, you declare a single preset entry that returns all three.
The preset system is implemented in the core server package at packages/docusaurus/src/server/plugins/presets.ts. This file contains the registry logic that maps preset names (like "classic") to their implementation functions and handles the merging of preset-generated configuration into your site.
The Preset Registry and Core Architecture
Docusaurus maintains an internal preset registry that resolves string names or module paths to preset functions. When the development server or build process starts, the core loads each preset defined in the presets array of your configuration file.
| Component | Purpose | Source Location |
|---|---|---|
| Preset Registry | Maps preset names to implementation functions and validates the preset contract. | packages/docusaurus/src/server/plugins/presets.ts |
| Preset Context | Provides runtime information including site directory paths, site configuration, and version metadata to the preset function. | packages/docusaurus/src/server/plugins/presets.ts |
| Preset Function | User-defined or built-in function that receives context and options, then returns plugins, themes, and config overrides. | User modules or core packages |
| Return Shape | Standardized object containing plugins, themes, and optional config keys that Docusaurus merges into the final site config. |
Defined in presets.ts |
The Preset Context and Return Shape
Every preset function receives two arguments: the preset context (containing paths and site metadata) and an options object (containing user-specified overrides). The function must return an object adhering to the following structure:
{
plugins: PluginConfig[], // Array of plugin entries to register
themes: ThemeConfig[], // Array of theme entries to load
config?: Partial<SiteConfig> // Optional site configuration overrides
}
This return value is merged with your root docusaurus.config.js settings, with later presets in the array taking precedence over earlier ones.
How Docusaurus Resolves Presets
The resolution process occurs during the server initialization phase in packages/docusaurus/src/server/plugins/presets.ts. The core executes the following steps:
- Reads the
presetsarray fromdocusaurus.config.js - Loads the preset module (resolving strings like
"classic"to built-in implementations or requiring custom file paths) - Invokes the preset function with the preset context and user-provided options
- Merges the returned values into the site's plugin and theme registries, applying configuration overrides
This architecture allows you to share complete documentation setups across projects or distribute them via npm as "starter kit" packages.
Using the Built-In Classic Preset
The classic preset is the most commonly used configuration in Docusaurus projects. It bundles the documentation plugin, blog plugin, and the classic theme into a single entry.
To use it, reference "classic" in your docusaurus.config.js:
// docusaurus.config.js
module.exports = {
title: 'My Documentation',
url: 'https://example.com',
baseUrl: '/',
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/example/repo/edit/main/',
},
blog: {
showReadingTime: true,
postsPerPage: 5,
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
}),
],
],
};
The string 'classic' resolves to the implementation exported by @docusaurus/preset-classic, which internally returns the standard set of content plugins and the classic theme. The options object configures each bundled plugin according to the Options type interface.
Creating Custom Docusaurus Presets
You can author custom presets to standardize configurations across multiple documentation sites in an organization.
Defining a Custom Preset Function
Create a JavaScript file that exports a function receiving context and options:
// my-preset/index.js
module.exports = function myPreset(context, options) {
return {
plugins: [
require.resolve('@docusaurus/plugin-content-docs'),
require.resolve('@docusaurus/plugin-content-blog'),
require.resolve('./local-search-plugin'), // Custom local plugin
],
themes: [
require.resolve('@docusaurus/theme-classic'),
],
config: {
themeConfig: {
navbar: {
title: 'Enterprise Docs',
items: [
{ to: '/docs/intro', label: 'Documentation', position: 'left' },
{ to: '/blog', label: 'Release Notes', position: 'left' },
],
},
footer: {
style: 'dark',
copyright: `Copyright © ${new Date().getFullYear()} My Organization`,
},
},
},
};
};
This example demonstrates the pattern found in the test fixtures at packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts, where presets return multiple plugins and configuration overrides.
Applying Custom Presets in Your Configuration
Reference your local or npm-published preset using require.resolve:
// docusaurus.config.js
module.exports = {
// ... other config
presets: [
[
require.resolve('./my-preset'),
{
// Preset-specific options passed to the function's `options` parameter
blogEnabled: true,
},
],
],
};
Overriding Preset Options
When using any preset, you can selectively override its default behavior by providing an options object. The preset function receives these options and typically merges them with internal defaults before constructing the plugin list:
presets: [
[
'classic',
{
// Disable the blog entirely
blog: false,
// Configure docs with custom path
docs: {
routeBasePath: '/',
sidebarPath: require.resolve('./sidebars.js'),
},
// Keep theme but use custom CSS
theme: {
customCss: require.resolve('./src/css/enterprise-theme.css'),
},
},
],
];
Summary
- Docusaurus preset configurations bundle plugins, themes, and site settings into single reusable units managed in
packages/docusaurus/src/server/plugins/presets.ts. - The classic preset provides the standard documentation, blog, and theming setup via a single configuration entry.
- Custom presets follow a standard contract: export a function that receives preset context and returns
{ plugins, themes, config }. - Presets are resolved in order from the
presetsarray, with later entries overriding earlier configuration values. - You can mix built-in presets with custom local presets to create standardized documentation stacks for enterprise environments.
Frequently Asked Questions
What is the difference between a Docusaurus preset and a plugin?
A plugin is a single functional unit that loads content or modifies the build process (like generating documentation pages). A preset is a higher-level aggregator that returns multiple plugins, themes, and configuration values. While plugins do the actual work, presets are convenience packages that wire multiple plugins together with sensible defaults, as implemented in the core preset loading logic at packages/docusaurus/src/server/plugins/presets.ts.
Can I use multiple presets in one Docusaurus project?
Yes, you can declare multiple entries in the presets array. Docusaurus processes them sequentially and merges their returned plugins, themes, and configuration objects. Be aware that if two presets register conflicting plugins or theme settings, the later preset in the array will take precedence during the merge operation performed by the preset resolution system.
How do I override specific options in the classic preset?
Pass a configuration object as the second element in your preset entry array. The classic preset accepts options for docs, blog, pages, and theme keys. These options are passed directly to the respective plugins after being merged with the preset's internal defaults. For example, setting blog: false disables the blog plugin entirely, while providing a theme.customCss path overrides the default stylesheet location.
Where are built-in presets like "classic" defined?
The "classic" preset name resolves to @docusaurus/preset-classic, which is maintained in the facebook/docusaurus monorepo. The mapping from the string name to the actual module occurs in the preset registry within packages/docusaurus/src/server/plugins/presets.ts. Additionally, the repository includes test fixtures such as packages/docusaurus/src/server/plugins/__tests__/__fixtures__/presets/preset-plugins.ts that demonstrate how presets structure their return objects for both plugins and themes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →