Skip to main content

Preparing your site for Docusaurus v3

Β· 13 min read
SΓ©bastien Lorber

Docusaurus v3 is now in beta and the official release is around the corner. This is the perfect time to start preparing your site for this new major version.

Docusaurus v3 comes with a few breaking changes, many of which can be handled today under Docusaurus v2. Preparing your site ahead of time can be done incrementally, and will make it easier to upgrade to v3.

The most important Docusaurus v3 breaking change is the upgrade to MDX v2, which will compile your Markdown content more strictly and with subtle differences.

This article will mostly focus on how to prepare your content for this new MDX version, and will also list a few other breaking changes that you can handle today.

Preparing your site for Docusaurus v3 - social card

warning

This article mentions most Docusaurus v3 breaking changes, but is exhaustive. Read the v3.0.0-beta.0 release notes for an exhaustive list.

Don't be afraid

There's a lot of content in this blog post, but many Docusaurus v2 sites can upgrade with very few changes.

If your site is relatively small, with only a few customizations, you can probably upgrade to Docusaurus v3 immediately.

Preparatory work​

Before preparing for the Docusaurus v3 upgrade, we recommend upgrading to the latest Docusaurus v2 version.

Depending on the complexity of your site, it may be a good idea to adopt the visual regression testing workflow that we recently presented. It could help you catch unexpected visual side effects occurring during the Docusaurus v3 upgrade.

We also recommend using the .mdx extension whenever you use JSX, import, or export (i.e. MDX features) inside a Markdown file. It is semantically more correct and improves compatibility with external tools (IDEs, formatters, linters, etc.). In future versions of Docusaurus, .md files will be parsed as standard CommonMark, which does not support these features. In Docusaurus v3, .md files keep being compiled as MDX files, but it will be possible to opt-in for CommonMark.

Preparing content for MDX v2​

MDX is a major dependency of Docusaurus responsible for compiling your .md and .mdx files to React components.

MDX v2 is much better, but also comes with changes that probably require you to refactor your content a bit. MDX v2 is stricter, and some components that compiled fine under v1 might now fail to compile under v2, most likely because of { and < characters.

Upgrading MDX comes with all the breaking changes documented on the MDX v2 release blog post. The MDX v2 migration guide has a section on how to update MDX files that will be particularly relevant to us. Also make sure to read the Troubleshooting MDX page that can help you interpret common MDX error messages.

Make sure to also read our updated MDX and React documentation page.

Ask for help

We have a dedicated MDX v2 - Upgrade Support discussion.

Using the MDX playground​

The MDX playground is your new best friend. It permits to understand how your content is compiled to React components, and troubleshoot compilation or rendering issues in isolation.

Each MDX version comes with its own playground:

Configuring MDX v2 playground options for Docusaurus

To obtain a compilation behavior similar to what Docusaurus v2 uses, please turn on these options on the MDX v2 playground:

  • Use MDX
  • Use remark-gfm
  • Use remark-directive

Screenshot of the MDX v2 playground&#39;s options panel, with only the &quot;Use MDX&quot;, &quot;Use remark-gfm&quot;, and &quot;Use remark-directive&quot; options checked

Using the two MDX playgrounds side-by-side, you will soon notice that some content is compiled differently or fails to compile in v2.

Making your content future-proof

The goal will be to refactor your problematic content so that it works fine with both versions of MDX. This way, when you upgrade to Docusaurus v3, this content will already work out-of-the-box.

Using the MDX checker CLI​

We provide a docusaurus-mdx-checker CLI that permits to easily spot problematic content. Run this command today on your Docusaurus v2 site to obtain a list of files that will fail to compile under MDX v2.

npx docusaurus-mdx-checker

For each compilation issue, the CLI will log the file path and a line number to look at.

Screenshot of the terminal showing an example MDX checker CLI output, with a few error messages

tip

Use this CLI to estimate of how much work will be required to make your content compatible with MDX v2.

warning

This CLI is a best effort, and will only report compilation errors.

It will not report subtle compilation changes that do not produce errors but can affect how your content is displayed. To catch these problems, we recommend using visual regression tests.

Common MDX problems​

We upgraded a few Docusaurus sites to Docusaurus v3 and MDX v2:

These upgrades permitted us to aggregate the most common content problems, and document how to best handle them.

Bad usage of {​

The { character is used for opening JavaScript expressions. MDX v2 will now fail if what you put inside {expression} is not a valid expression.

example.md
The object shape looks like {username: string, age: number}
Error message

Could not parse expression with acorn: Unexpected content after expression

How to prepare

Available options to fix this error:

  • Use inline code: {username: string, age: number}
  • Use the HTML code: &#123;
  • Escape it: \{

Bad usage of <​

The < character is used for opening JSX tags. MDX v2 will now fail if it thinks your JSX is invalid.

example.md
Use Android version <5

You can use a generic type like Array<T>

Follow the template "Road to <YOUR_MINOR_VERSION>"
Error messages

Unexpected character 5 (U+0035) before name, expected a character that can start a name, such as a letter, $, or _

Expected a closing tag for <T> (1:6-1:9) before the end of paragraph end-tag-mismatch mdast-util-mdx-jsx

Expected a closing tag for <YOUR_MINOR_VERSION> (134:19-134:39) before the end of paragraph

How to prepare

Available options to fix this error:

  • Use inline code: Array<T>
  • Use the HTML code: &lt; or &#60;
  • Escape it: \< (unfortunately the \ will be displayed under MDX v1)

Docusaurus supports GitHub Flavored Markdown (GFM), but autolink using the <link> syntax is not supported anymore by MDX v2.

example.md
<sebastien@thisweekinreact.com>

<http://localhost:3000>
Error messages

Unexpected character @ (U+0040) in name, expected a name character such as letters, digits, $, or _; whitespace before attributes; or the end of the tag (note: to create a link in MDX, use [text](url))

Unexpected character / (U+002F) before local name, expected a character that can start a name, such as a letter, $, or _ (note: to create a link in MDX, use [text](url))

How to prepare

Use regular Markdown links, or remove the < and >. MDX and GFM are able to autolink literals already.

example.md
sebastien@thisweekinreact.com
[sebastien@thisweekinreact.com](mailto:sebastien@thisweekinreact.com)

http://localhost:3000
[http://localhost:3000](http://localhost:3000)

Unintended extra paragraphs​

In MDX v2, it is now possible to interleave JSX and Markdown more easily without requiring extra line breaks. Writing content on multiple lines can also produce new expected <p> tags.

visual difference

See how this content is rendered differently by MDX v1 and v2.

example.md
<div>Some **Markdown** content</div>
<div>
Some **Markdown** content
</div>
MDX v1 output
<div>Some **Markdown** content</div>
<div>Some **Markdown** content</div>
MDX v2 output
<div>Some <strong>Markdown</strong> content</div>
<div><p>Some <strong>Markdown</strong> content</p></div></div>
How to prepare

If you don't want an extra <p> tag, refactor content on a case by case basis to use a single-line JSX tag.

 <figure>
<img src="/img/myImage.png" alt="My alt" />
- <figcaption>
- My image caption
- </figcaption>
+ <figcaption>My image caption</figcaption>
</figure>

If your content contains "Markdown inlines" (**, *, _, [link](/path)), you might not be able to refactor it ahead of time, and will have to do it alongside the Docusaurus v3 upgrade.

Unintended usage of directives​

Docusaurus v3 now uses Markdown Directives (implemented with remark-directive) as a generic way to provide support for admonitions, and other upcoming Docusaurus features.

example.md
This is a :textDirective

::leafDirective

:::containerDirective

Container directive content

:::
Visual change

Directives are parsed with the purpose of being handled by other Remark plugins. Unhandled directives will be ignored, and won't be rendered back in their original form.

example.md
The AWS re:Invent conf is great

Due to :Invent being parsed as a text directive, this will now be rendered as:

The AWS re
conf is great
How to prepare
  • Use the HTML code: &#58;
  • Add a space after : (if it makes sense): : text
  • Escape it: \: (unfortunately the \ will be displayed under MDX v1)

Unsupported indented code blocks​

MDX v2 does not transform indented text as code blocks anymore.

example.md
    console.log("hello");
Visual change

The upgrade does not generally produce new MDX v2 compilation errors, but can lead to content being rendered in an unexpected way because there isn't a code block anymore.

How to prepare

Use the regular code block syntax instead of indentation:

example.md
```js
console.log('hello');
```

MDX plugins​

All the official packages (Unified, Remark, Rehype...) in the MDX ecosystem are now ES Modules only and do not support CommonJS anymore.

In practice this means that you can't do require("remark-plugin") anymore. Unfortunately the Docusaurus config file only supports CommonJS at the moment, and you can't use import MyRemarkPlugin from "remark-plugin".

How to prepare

Using dynamic imports is a good workaround that enables you to import ES modules inside a CommonJS module. Fortunately, the Docusaurus config supports the usage of an async function to let you do so.

You can start refactoring your config to use async dynamic imports today. Refer to the MDX plugin installation documentation for details.

docusaurus.config.js
module.exports = async function () {
const myPlugin = (await import('remark-plugin')).default;
return {
// site config...
};
};
For plugin authors

If you created custom Remark or Rehype plugins, you may need to refactor those, or eventually rewrite them completely, due to how the new AST is structured. We have created a dedicated support discussion to help plugin authors upgrade their code.

Other breaking changes​

Apart from MDX, there are other breaking changes that you can already prepare your site for, notably major version upgrades of important dependencies.

Node.js 18.0​

Node.js 16 reached End-of-Life, and Docusaurus v3 now requires Node.js >= 18.0.

How to prepare

Upgrade your Docusaurus v2 site to Node.js 18 before upgrading to Docusaurus v3.

React 18​

Docusaurus v3 now requires React >= 18.0.

React 18 comes with its own breaking changes that should be relatively easy to handle, depending on the amount of custom React code you created for your site.

Simple Docusaurus sites that only use our official theme code without swizzling do not have anything to do.

How to prepare

Read the official React v18.0 and How to Upgrade to React 18, and look at your first-party React code to figure out which components might be affected this React 18 upgrade.

We recommend to particularly look for:

  • Automatic batching for stateful components
  • New React hydration errors reported to the console

TypeScript 5.0​

Docusaurus v3 now requires TypeScript >= 5.0.

How to prepare

Upgrade your Docusaurus v2 site to TypeScript 5 before upgrading to Docusaurus v3.

TypeScript base config​

The official Docusaurus TypeScript config has been re-internalized from the external package @tsconfig/docusaurus to our new monorepo package @docusaurus/tsconfig.

This new package is versioned alongside all the other Docusaurus core packages, and will be used to ensure TypeScript retro-compatibility and breaking changes on major version upgrades.

How to prepare

The new Docusaurus v3 TypeScript config is sensibly the same as the former Docusaurus v2 TypeScript config. If you upgraded to TypeScript 5, using the Docusaurus v3 config on a v2 site is already possible:

package.json
 {
"devDependencies": {
- "@tsconfig/docusaurus": "^1.0.7",
+ "@docusaurus/tsconfig": "^3.0.0-beta.0",
}
}
tsconfig.json
 {
- "extends": "@tsconfig/docusaurus/tsconfig.json",
+ "extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
}
}

Admonition warning​

For historical reasons, we support an undocumented admonition :::warning that renders with a red color.

Warning

This is a Docusaurus v2 :::warning admonition.

However, the color and icon is historically wrong. Docusaurus v3 re-introduces :::warning admonition officially, documents it, and fix the color and icon.

warning

This is a Docusaurus v3 :::warning admonition.

How to prepare

If you previously used the undocumented :::warning admonition, make sure to verify for each usage if yellow is now an appropriate color. If you want to keep the red color, use :::danger instead.

Docusaurus v3 also deprecated the :::caution admonition. Please refactor :::caution (yellow) to either :::warning (yellow) or :::danger (red).

Versioned sidebars​

This breaking change will only affect Docusaurus v2 early adopters who versioned their docs before v2.0.0-beta.10 (December 2021).

When creating version v1.0.0, the sidebar file contained a prefix version-v1.0.0/ that Docusaurus v3 does not support anymore.

versioned_sidebars/version-v1.0.0-sidebars.json
{
"version-v1.0.0/docs": [
"version-v1.0.0/introduction",
"version-v1.0.0/prerequisites"
]
}
How to prepare

Your Docusaurus v2 site is able to handle the 2 sidebar formats similarly.

You can remove the useless versioned prefix from your versioned sidebars.

versioned_sidebars/version-v1.0.0-sidebars.json
{
"docs": ["introduction", "prerequisites"]
}

Try Docusaurus v3 today​

Docusaurus v3 is now in beta, and already used in production by React-Native, Jest, and our own website.

We think this new Docusaurus version is robust and ready to be deployed in production. It should be released officially soon, after receiving a positive feedback from early adopters of our community.

We would really appreciate it if you try upgrading and report issues on the 3.0.0-beta.0 release discussion thread.

For most sites, the upgrade should be easy. If you prepared your site ahead of time as documented here, upgrading the following dependencies should be enough:

package.json
 {
"dependencies": {
- "@docusaurus/core": "2.4.3",
- "@docusaurus/preset-classic": "2.4.3",
- "@mdx-js/react": "^1.6.22",
+ "@docusaurus/core": "3.0.0-beta.0",
+ "@docusaurus/preset-classic": "3.0.0-beta.0",
+ "@mdx-js/react": "^2.3.0",
"clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5",
- "react": "^17.0.2",
- "react-dom": "^17.0.2"
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
},
"devDependencies": {
- "@docusaurus/module-type-aliases": "2.4.3"
+ "@docusaurus/module-type-aliases": "3.0.0-beta.0"
}
}

Ask for help​

We will be there to help you upgrade through the following support channels:

Alternatively, you can look for a paid Docusaurus Service Provider to execute this upgrade for you. If your site is open source, you can also ask our community for free, benevolent help.

Conclusion​

Docusaurus v3 is ready to try, and will be released soon. This article already gives you a good idea of all the major changes required to upgrade.

The initial 3.0 release is focusing on dependency and infrastructure upgrades that will permit us to implement new exciting features. It also comes with a few useful features that we will detail in the final release notes.