Overview

Docusaurus is a popular documentation framework from Meta. HolyDocs can automatically convert your Docusaurus project, including the docusaurus.config.js theme settings, sidebars.js navigation structure, and MDX content with admonitions and other Docusaurus-specific syntax.

HolyDocs migrates the docs portion of Docusaurus projects. Blog posts, custom pages, and React-based pages are not included in the migration since HolyDocs is purpose-built for documentation.

Automatic Migration

bash
# Install HolyDocs CLInpm install -g holydocs# Migrate from your Docusaurus project directoryholydocs migrate --from docusaurus# Preview without modifying filesholydocs migrate --from docusaurus --dry-run

The CLI auto-detects Docusaurus projects by the presence of docusaurus.config.js or docusaurus.config.ts.

What Gets Converted

1

docusaurus.config.js becomes docs.json

Theme configuration, site metadata, navbar items, and footer links are extracted and mapped to docs.json fields.

2

sidebars.js becomes navigation

Sidebar items — including categories, auto-generated sidebars, and document references — are converted to HolyDocs navigation.tabs[].groups structure.

3

Admonitions become Callouts

Docusaurus admonition syntax (:::note, :::tip, etc.) is converted to HolyDocs Callout components.

4

MDX components are mapped

Docusaurus-specific imports and components like <Tabs>, <TabItem>, and <Details> are converted to their HolyDocs equivalents.

5

Frontmatter is preserved

Page frontmatter fields like title, description, sidebar_label, and sidebar_position are preserved or remapped.

Configuration Mapping

docusaurus.config.js to docs.json

docusaurus.config.jsdocs.jsonNotes
titlenameSite title
faviconfaviconDirect mapping
themeConfig.navbar.titlenameFallback if title not set
themeConfig.navbar.logologoMaps src and srcDark to light and dark
themeConfig.navbar.itemsnavbar.linksExternal links become header links
themeConfig.colorMode.defaultModeappearance.default"light" or "dark"
themeConfig.colorMode.disableSwitchappearance.strictBoolean mapping
themeConfig.footer.linksfooter.socials / footer.linksSocial links and grouped footer columns
themeConfig.algoliaReplaced by built-in HolyDocs search
urlUsed for canonical URL generation
baseUrlUsed during path resolution

Theme Colors

Docusaurus uses CSS custom properties for theming. The migration extracts the primary color from custom.css or themeConfig:

css
/* Docusaurus custom.css */:root { --ifm-color-primary: #2e8555;}

This becomes:

json
{ "colors": { "primary": "#2e8555" }}

sidebars.js to docs.json Navigation

Docusaurus sidebars support several item types. Each is handled during migration:

Sidebar Item Typedocs.json Mapping
type: 'doc'Page reference in groups[].pages
type: 'category'Navigation group (groups[].group)
type: 'link'External link (added to topbar or group)
type: 'autogenerated'Resolved from directory structure
type: 'ref'Same as doc (cross-sidebar reference)
String shorthandPage reference in groups[].pages
javascript
module.exports = { docs: [ { type: 'category', label: 'Getting Started', items: [ 'intro', 'installation', 'quick-start', ], }, { type: 'category', label: 'Guides', items: [ 'guides/authentication', 'guides/pagination', { type: 'category', label: 'Advanced', items: [ 'guides/advanced/webhooks', 'guides/advanced/rate-limiting', ], }, ], }, { type: 'category', label: 'API Reference', items: [ { type: 'autogenerated', dirName: 'api', }, ], }, ],};

Deeply nested Docusaurus categories (3+ levels) are flattened into two-level groups. Page paths are preserved so links remain valid.

Multiple Sidebars

If your Docusaurus project uses multiple sidebars, each becomes a separate tab in HolyDocs:

javascript
// sidebars.jsmodule.exports = { docs: [/* ... */], api: [/* ... */], community: [/* ... */],};

Becomes three tabs: "Docs", "API", and "Community" in docs.json.

Content Conversion

Admonitions to Callouts

Docusaurus uses a triple-colon syntax for admonitions. These are converted to HolyDocs Callout components.

markdown
:::noteThis is a note admonition.::::::tipA helpful tip for the reader.::::::infoAdditional context or background.::::::cautionProceed with care.::::::dangerThis action is irreversible.::::::note[Custom Title]A note with a custom title.:::
Docusaurus AdmonitionHolyDocs Callout Type
:::note<Callout type="note">
:::tip<Callout type="tip">
:::info<Callout type="info">
:::caution<Callout type="caution">
:::danger<Callout type="warning">

Tabs and TabItem

mdx
import Tabs from '@theme/Tabs';import TabItem from '@theme/TabItem';<Tabs> <TabItem value="js" label="JavaScript"> ```javascript const data = await fetch('/api'); ``` </TabItem> <TabItem value="py" label="Python"> ```python data = requests.get('/api') ``` </TabItem></Tabs>

The migration:

  • Removes import statements for @theme/Tabs and @theme/TabItem
  • Renames <TabItem> to <Tab>
  • Converts the label prop to title
  • Removes the value prop (not needed in HolyDocs)

Details to Accordion

mdx
<details> <summary>Click to expand</summary> Detailed content that is hidden by default.</details>

Code Blocks

Docusaurus code blocks with the title attribute are converted to HolyDocs code blocks:

markdown
```javascript title="src/index.js"console.log('Hello');```

Code block titles are supported natively in HolyDocs, so no conversion is needed for this syntax.

React Component Handling

Docusaurus allows importing custom React components in MDX files. HolyDocs does not support arbitrary React imports since content is pre-rendered at build time.

Custom React components imported from @site/src/components or local paths will not work in HolyDocs. The migration CLI reports these imports so you can replace them with built-in HolyDocs components or static content.

Common Replacements

Docusaurus ComponentHolyDocs Alternative
Custom <Card> componentBuilt-in <Card> component
Custom <Banner> or <Hero><Callout> with appropriate type
<CodeBlock> importNative fenced code blocks
@theme/TOCInlineAutomatic TOC (configured in docs.json)
@theme/DocCardList<CardGroup> with <Card> items
BrowserOnly wrapperNot needed (no client-side rendering)

Handling MDX v1 vs v2 Syntax

Docusaurus v2 uses MDX v1, while Docusaurus v3 uses MDX v2. HolyDocs uses MDX v2+ syntax. Key differences:

MDX v1 (Docusaurus v2)MDX v2+ (HolyDocs)
{/* comment */}{/* comment */} (same)
Indented JSX under listsRequires explicit newline before JSX
<img> self-closing optional<img /> self-closing required
Unescaped { in textMust escape as \{
Unescaped < in textMust escape as \< or use &lt;

Run holydocs check after migration to catch any MDX v2 syntax issues. The checker reports exact line numbers and suggested fixes.

Frontmatter Mapping

Docusaurus FrontmatterHolyDocs FrontmatterNotes
titletitleDirect mapping
descriptiondescriptionDirect mapping
sidebar_labelsidebarTitleRenamed
sidebar_positionOrdering is defined in docs.json navigation
slugURL paths are file-path based
tagstagsDirect mapping
hide_titlehideTitleRenamed
hide_table_of_contentstoctrue becomes false (inverted)
keywordsseo.keywordsMoved under seo
imageseo.ogImageUsed for Open Graph
draftdraftDirect mapping

Verification

1

Validate the project

bash
holydocs check

Pay attention to:

  • MDX syntax errors (especially if migrating from Docusaurus v2 / MDX v1)
  • Missing page references in navigation
  • Unresolved React component imports
2

Preview locally

bash
holydocs dev

Check each section of your docs for:

  • Correct navigation structure
  • Properly rendered callouts (no raw ::: syntax)
  • Working tabs and accordions
  • Images loading correctly
3

Search for unconverted syntax

Look for any remaining Docusaurus-specific syntax:

bash
# Check for remaining admonitionsgrep -r "^:::" --include="*.mdx" .# Check for Docusaurus importsgrep -r "@theme/" --include="*.mdx" .grep -r "@site/" --include="*.mdx" .# Check for TabItem usagegrep -r "TabItem" --include="*.mdx" .
4

Deploy

bash
holydocs deploy

Common Issues

This is most often caused by MDX v1 syntax that is invalid in MDX v2. Common culprits include unescaped curly braces { in text content, HTML comments <!-- --> (use {/* */} instead), and self-closing HTML tags without the slash. Run holydocs check for exact error locations.

Docusaurus supports arbitrarily deep category nesting. HolyDocs uses a two-level structure (tabs and groups). Categories deeper than two levels are flattened into the nearest parent group. The page paths and content remain unchanged.

Components imported from @theme/ or @site/src/components are not available in HolyDocs. Replace them with built-in HolyDocs components. The migration CLI lists all unresolved imports in its output.

HolyDocs migrates only the docs portion of a Docusaurus site. Blog posts, custom pages, and standalone React pages are not included. If you need to preserve this content, consider keeping a separate Docusaurus instance for the blog.

Docusaurus plugins (like docusaurus-plugin-openapi, docusaurus-plugin-sass, etc.) are not migrated. HolyDocs has built-in equivalents for common plugins:

Docusaurus PluginHolyDocs Equivalent
docusaurus-plugin-openapiBuilt-in openapi config + API playground
@docusaurus/plugin-google-analyticsanalytics.googleAnalytics in docs.json
@docusaurus/plugin-sitemapAutomatic sitemap generation
docusaurus-plugin-sasscustomCss in docs.json

Docusaurus versioned docs (in versioned_docs/ and versioned_sidebars/) are not automatically migrated. HolyDocs has its own versioning system. Migrate your current docs first, then set up versioning through the HolyDocs dashboard. See the versioning documentation for details.

Ask a question... ⌘I