# How to Migrate from Docusaurus v2 to v3: Complete Upgrade Guide

> Upgrade to Docusaurus v3 with our comprehensive guide. Learn to update packages, restructure config, and replace plugins for a smooth migration. Get started now!

- Repository: [Meta/docusaurus](https://github.com/facebook/docusaurus)
- Tags: migration-guide
- Published: 2026-03-04

---

**Migrating from Docusaurus v2 to v3 requires updating core packages to v3 releases, restructuring [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js) to move `themeConfig` outside the preset array, replacing deprecated plugins like `@docusaurus/plugin-google-analytics` with `@docusaurus/plugin-google-gtag`, and running the automated migration CLI to handle MDX 2 compatibility and configuration updates.**

Docusaurus v3 introduces breaking changes including MDX 2 support, a new bundler abstraction, and restructured configuration patterns while maintaining the zero-config philosophy. This guide walks through the complete migration process based on the official source code in the `facebook/docusaurus` repository, covering manual configuration updates and automated tooling.

## Upgrade Core Packages to v3

The first step to migrate from Docusaurus v2 to v3 is updating your [`package.json`](https://github.com/facebook/docusaurus/blob/main/package.json) dependencies to the latest v3 releases. Docusaurus v3 ships with a new bundler abstraction (`docusaurus-bundler`) that defaults to Webpack 5/Rspack, replacing the legacy Webpack 4 configuration from v2.

Update your core dependencies using your package manager:

```bash
yarn add @docusaurus/core@latest @docusaurus/preset-classic@latest
yarn add @docusaurus/plugin-content-docs@latest @docusaurus/plugin-content-blog@latest

```

The **preset-classic** package in v3 requires that you restructure how options are passed, while individual content plugins maintain their exported APIs but may have relocated configuration keys. After updating dependencies, delete your `node_modules` folder and lockfile to ensure no stale v2 packages remain.

## Restructure docusaurus.config.js

The most significant configuration change when you migrate from Docusaurus v2 to v3 involves the placement of `themeConfig`. In v2, `themeConfig` lived inside the preset options array; in v3, it must be placed at the root level of the configuration object.

### Move themeConfig Outside the Preset

In [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js), relocate the `themeConfig` object from inside the preset configuration to the root level:

**v2 Configuration (Deprecated):**

```javascript
presets: [
  [
    '@docusaurus/preset-classic',
    {
      docs: { sidebarPath: require.resolve('./sidebars.js') },
      theme: { customCss: require.resolve('./src/css/custom.css') },
      themeConfig: { 
        navbar: { /* ... */ }, 
        footer: { /* ... */ } 
      },
    },
  ],
],

```

**v3 Configuration (Current):**

```javascript
presets: [
  [
    '@docusaurus/preset-classic',
    {
      docs: { sidebarPath: require.resolve('./sidebars.js') },
      theme: { customCss: require.resolve('./src/css/custom.css') },
    },
  ],
],
themeConfig: {
  navbar: { /* ... */ },
  footer: { /* ... */ },
},

```

According to the migration documentation in [`migration-overview.mdx`](https://github.com/facebook/docusaurus/blob/main/website/docs/migration/v2/migration-overview.mdx), this change simplifies how the classic preset merges configuration options with the theme system.

## Adjust Sidebar Type Definitions

If your project uses TypeScript for sidebar definitions, update the type import for `SidebarsConfig`. While the structural shape of [`sidebars.js`](https://github.com/facebook/docusaurus/blob/main/sidebars.js) or [`sidebars.ts`](https://github.com/facebook/docusaurus/blob/main/sidebars.ts) remains unchanged, you should verify the import source comes from the v3 version of `@docusaurus/plugin-content-docs`.

```typescript
// sidebars.ts
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';

export const sidebars: SidebarsConfig = {
  tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }],
};

```

The sidebar migration details are documented in [`migration-manual.mdx`](https://github.com/facebook/docusaurus/blob/main/website/docs/migration/v2/migration-manual.mdx), which confirms that autogenerated sidebars and explicit sidebar definitions require no structural changes during the upgrade.

## Replace Deprecated Plugins and Themes

Several official plugins and themes were deprecated or restructured in v3. You must replace these before building your site.

| v2 Plugin | v3 Replacement | Configuration Changes |
|-----------|----------------|----------------------|
| `@docusaurus/plugin-google-analytics` | `@docusaurus/plugin-google-gtag` | Install the gtag plugin and update `trackingID` to `gtagId` |
| `@docusaurus/plugin-ideal-image` | Same package, updated version | Upgrade to latest version; API remains compatible |
| `@docusaurus/plugin-sitemap` | Still available | Verify config matches new schema; `changefreq` and `priority` remain valid |

To install the replacement for Google Analytics:

```bash
yarn add @docusaurus/plugin-google-gtag@latest

```

Then update your `themeConfig` to use the `gtag` key instead of the old `googleAnalytics` configuration.

## Adapt Content for MDX 2

Docusaurus v3 upgrades the default MDX processor from v1 to v2, which enforces stricter parsing rules. Most existing content works without changes, but you must verify that **React component imports** follow MDX 2 syntax standards.

Remove any implicit component imports that relied on v1's magic imports feature. If you previously placed components in a `components/` folder for automatic availability, you must now explicitly import them in your MDX files or register them globally via the `theme` configuration in [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js).

Front matter fields like `slug`, `title`, and `description` remain fully supported. The `sidebar_position` field is now optional, and you can use `sidebar_label` directly to control navigation text without additional configuration.

## Execute the Automated Migration CLI

Docusaurus provides a dedicated CLI command to automate many mechanical changes when you migrate from Docusaurus v2 to v3. This tool updates [`package.json`](https://github.com/facebook/docusaurus/blob/main/package.json) dependencies, rewrites configuration structures, and flags content requiring manual review.

Run the migration command from your project root:

```bash
npx @docusaurus/migrate@latest v2-to-v3 .

```

The automated migration performs these actions:

1. Bumps all `@docusaurus/*` dependencies to their latest v3 releases
2. Transforms [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js) to the new preset layout
3. Adjusts plugin configurations and generates warnings for manual fixes still required

Review the generated changes with `git diff` before committing. The CLI implementation is documented in [`migration-automated.mdx`](https://github.com/facebook/docusaurus/blob/main/website/docs/migration/v2/migration-automated.mdx).

## Verify the Build and Update CI

After applying automated and manual changes, verify your site builds correctly:

```bash
yarn install
yarn build
yarn serve

```

Check the console for deprecation warnings during the build process. Open `http://localhost:3000` to verify that documentation pages, blog posts, versioned docs, and internationalized routes render correctly.

Pay special attention to the `siteUrl` and `baseUrl` configuration—v3 enforces trailing slash policies that differ from v2 behavior, which may affect your deployment URLs.

Update your CI/CD scripts to accommodate v3 requirements:

- Use `yarn docusaurus build` explicitly instead of legacy shortcuts
- Set `NODE_OPTIONS=--max_old_space_size=4096` for large sites to prevent memory exhaustion during the Webpack 5/Rspack bundling process
- Verify that deployment scripts reference the correct `build/` output directory, which remains unchanged from v2

## Summary

- **Upgrade packages** to v3 releases including `@docusaurus/core` and `@docusaurus/preset-classic` to access the new Webpack 5/Rspack bundler
- **Restructure configuration** by moving `themeConfig` from inside the preset array to the root of [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js)
- **Update sidebar types** to import from the v3 version of `@docusaurus/plugin-content-docs` if using TypeScript
- **Replace deprecated plugins** such as swapping `@docusaurus/plugin-google-analytics` for `@docusaurus/plugin-google-gtag`
- **Run the migration CLI** using `npx @docusaurus/migrate@latest v2-to-v3 .` to automate mechanical updates
- **Verify builds** locally and update CI scripts to set appropriate Node memory limits for the new bundler

## Frequently Asked Questions

### Can I migrate from Docusaurus v2 to v3 automatically without manual changes?

The automated migration CLI handles dependency updates, configuration restructuring, and basic MDX 2 compatibility fixes. However, you must manually verify custom plugins, CSS modules, and complex React components within documentation pages. Run the CLI first, then review the generated diff to identify sections requiring manual intervention.

### What breaking changes in MDX 2 affect existing documentation?

MDX 2 enforces stricter parsing compared to v1, particularly regarding HTML-like syntax inside Markdown and implicit component imports. Curly braces must be escaped when not intended as expressions, and components must be explicitly imported rather than relying on magic directory-based resolution. Most standard Markdown content works without modification.

### Why was themeConfig moved outside the preset configuration in v3?

This architectural change in [`docusaurus.config.js`](https://github.com/facebook/docusaurus/blob/main/docusaurus.config.js) separates theme-specific styling and navigation configuration from the preset's plugin orchestration. By placing `themeConfig` at the root level, Docusaurus v3 creates a clearer boundary between content processing (handled by presets and plugins) and presentation logic (handled by themes).

### How do I handle the Google Analytics plugin deprecation during migration?

Uninstall `@docusaurus/plugin-google-analytics` and install `@docusaurus/plugin-google-gtag@latest` as its replacement. Update your `themeConfig` to use the `gtag` object with `trackingID` (now renamed to `gtagId` in some contexts) and `anonymizeIP` settings. This aligns with Google's migration from Universal Analytics to Google Analytics 4.