Use when migrating Docusaurus projects from v2 to v3 — upgrade @docusaurus/React/MDX/prism dependencies, rewrite MDX v1 syntax to v3 (escape bare { and <, fix autolinks), swap @tsconfig/docusaurus for @docusaurus/tsconfig, update Prism imports, and resolve React 18 breaking changes. Triggers on tasks involving MDX v1 to v3 migration, Docusaurus dependency updates, React 18 compatibility, or v2/v3 breaking changes.
72
90%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
@docusaurus/core: ^2.x.x → ^3.0.0@docusaurus/preset-classic: ^2.x.x → ^3.0.0@mdx-js/react: ^1.6.22 → ^3.0.0prism-react-renderer: ^1.3.5 → ^2.1.0Replace @tsconfig/docusaurus with @docusaurus/tsconfig:
{
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
// your custom options
}
}The transition from MDX v1 to MDX v3 is the main challenge in adopting Docusaurus v3.
{ CharactersProblem: Bare braces are now invalid in MDX unless part of JSX expressions.
Bad:
Use the {key} to access the valueGood:
Use the `{key}` to access the value
Use the \{key\} to access the value< CharactersProblem: Bare angle brackets are invalid unless part of HTML/JSX.
Bad:
If x < 5, then...Good:
If `x < 5`, then...
If x \< 5, then...Problem: <email@example.com> and <https://example.com> no longer work.
Bad:
Contact us at <support@example.com>Good:
Contact us at [support@example.com](mailto:support@example.com)
Visit [https://example.com](https://example.com)Problem: Indented code blocks (4 spaces) are no longer recognized.
Bad:
Example code:
const foo = 'bar';Good:
Example code:
\`\`\`js
const foo = 'bar';
\`\`\`Problem: Emphasis marks next to spaces may not work as expected.
Bad:
This is _really _ importantGood:
This is _really_ importantOld (v1):
const lightTheme = require('prism-react-renderer/themes/github');
const darkTheme = require('prism-react-renderer/themes/dracula');New (v2):
const {themes} = require('prism-react-renderer');
const lightTheme = themes.github;
const darkTheme = themes.dracula;Prism React Renderer v2 includes fewer languages by default. Add required languages:
module.exports = {
themeConfig: {
prism: {
additionalLanguages: ['bash', 'diff', 'json'],
},
},
};React imports are no longer required in files using JSX:
Before:
import React from 'react';
export default function MyComponent() {
return <div>Hello</div>;
}After:
// No React import needed
export default function MyComponent() {
return <div>Hello</div>;
}React 18 has stricter hydration requirements. Ensure:
typeof windowuseEffect for client-only codenode --version (must be >=18.0)npx docusaurus-mdx-checker{
"dependencies": {
"@docusaurus/core": "^3.0.0",
"@docusaurus/preset-classic": "^3.0.0",
"@mdx-js/react": "^3.0.0",
"prism-react-renderer": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@docusaurus/tsconfig": "^3.0.0",
"@docusaurus/types": "^3.0.0",
"typescript": "~5.2.2"
},
"engines": {
"node": ">=18.0"
}
}{
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@site/*": ["./*"]
}
}
}npm installRun the checker and fix reported issues:
npx docusaurus-mdx-checkerCommon fixes:
{ and < in backticks or escape themUpdate Prism configuration:
const {themes} = require('prism-react-renderer');
module.exports = {
themeConfig: {
prism: {
theme: themes.github,
darkTheme: themes.dracula,
additionalLanguages: ['bash', 'diff', 'json'],
},
},
};npm startVisit http://localhost:3000 and check:
npm run buildFix any build errors before deploying.
Convert docusaurus.config.js to docusaurus.config.mjs:
import {themes} from 'prism-react-renderer';
export default {
// config
};Rename to docusaurus.config.ts:
import type {Config} from '@docusaurus/types';
import {themes} from 'prism-react-renderer';
const config: Config = {
// config
};
export default config;For files containing JSX, rename .md → .mdx:
# Example
mv blog/my-post.md blog/my-post.mdxIf using math support:
{
"remark-math": "^6.0.0",
"rehype-katex": "^7.0.0"
}Use the MDX Playground to debug:
Common causes:
React 18 is stricter about hydration. Check for:
windowIf code blocks don't highlight properly, add to additionalLanguages:
prism: {
additionalLanguages: ['java', 'php', 'ruby', 'python'],
}