From 0d89657090195d0113cea9078b8fc71a17d8bbb8 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 17:00:37 +0200 Subject: [PATCH 1/6] add future.v4.mdx1CompatDisabledByDefault flag --- packages/docusaurus-types/src/config.d.ts | 1 + packages/docusaurus-types/src/index.d.ts | 1 + .../server/__tests__/configValidation.test.ts | 93 ++++++++++++++++++- .../docusaurus/src/server/configValidation.ts | 44 ++++++--- website/docusaurus.config.ts | 3 +- 5 files changed, 121 insertions(+), 21 deletions(-) diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index b6d3d8a0a396..6f88b68dc6c6 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -41,6 +41,7 @@ export type FutureV4Config = { useCssCascadeLayers: boolean; siteStorageNamespacing: boolean; fasterByDefault: boolean; + mdx1CompatDisabledByDefault: boolean; }; // VCS (Version Control System) info about a given change, e.g., a git commit. diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 6d153c387a71..6dfca63d1f70 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -21,6 +21,7 @@ export { } from './config'; export { + MDX1CompatOptions, MarkdownConfig, MarkdownHooks, DefaultParseFrontMatter, diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index 63c58e82da1e..b97df9814d40 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -44,12 +44,26 @@ const baseConfig = { const normalizeConfig = (config: DeepPartial): DocusaurusConfig => validateConfig({...baseConfig, ...config}, 'docusaurus.config.js'); +// mdx1Compat defaults are resolved in postProcessDocusaurusConfig +// based on the future.v4.mdx1CompatDisabledByDefault flag +// DEFAULT_CONFIG.markdown.mdx1Compat is {} (unresolved) +// This is the resolved version when the flag is off (default) +const DEFAULT_MDX1_COMPAT_RESOLVED = { + comments: true, + admonitions: true, + headingIds: true, +}; + describe('normalizeConfig', () => { it('normalizes empty config', () => { const value = normalizeConfig({markdown: {}}); expect(value).toEqual({ ...DEFAULT_CONFIG, ...baseConfig, + markdown: { + ...DEFAULT_CONFIG.markdown, + mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, + }, }); }); @@ -67,6 +81,7 @@ describe('normalizeConfig', () => { useCssCascadeLayers: true, siteStorageNamespacing: true, fasterByDefault: true, + mdx1CompatDisabledByDefault: true, }, faster: { swcJsLoader: true, @@ -146,6 +161,10 @@ describe('normalizeConfig', () => { expect(value).toEqual({ ...DEFAULT_CONFIG, ...baseConfig, + markdown: { + ...DEFAULT_CONFIG.markdown, + mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, + }, customFields: { author: 'anshul', }, @@ -513,12 +532,17 @@ describe('markdown', () => { ): MarkdownConfig { return normalizeConfig({markdown}).markdown; } + const DEFAULT_MARKDOWN_RESOLVED = { + ...DEFAULT_CONFIG.markdown, + mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, + }; + it('accepts undefined object', () => { - expect(normalizeMarkdown(undefined)).toEqual(DEFAULT_CONFIG.markdown); + expect(normalizeMarkdown(undefined)).toEqual(DEFAULT_MARKDOWN_RESOLVED); }); it('accepts empty object', () => { - expect(normalizeMarkdown({})).toEqual(DEFAULT_CONFIG.markdown); + expect(normalizeMarkdown({})).toEqual(DEFAULT_MARKDOWN_RESOLVED); }); it('accepts valid markdown object', () => { @@ -558,10 +582,10 @@ describe('markdown', () => { }, }; expect(normalizeMarkdown(markdown)).toEqual({ - ...DEFAULT_CONFIG.markdown, + ...DEFAULT_MARKDOWN_RESOLVED, ...markdown, mdx1Compat: { - ...DEFAULT_CONFIG.markdown.mdx1Compat, + ...DEFAULT_MDX1_COMPAT_RESOLVED, ...markdown.mdx1Compat, }, }); @@ -1348,6 +1372,7 @@ describe('future', () => { useCssCascadeLayers: true, siteStorageNamespacing: true, fasterByDefault: true, + mdx1CompatDisabledByDefault: true, }, faster: { swcJsLoader: true, @@ -2566,6 +2591,7 @@ describe('future', () => { useCssCascadeLayers: true, siteStorageNamespacing: true, fasterByDefault: true, + mdx1CompatDisabledByDefault: true, }; expect( normalizeConfig({ @@ -2906,5 +2932,64 @@ describe('future', () => { `); }); }); + + describe('mdx1CompatDisabledByDefault', () => { + function mdx1CompatContaining(mdx1Compat: object) { + return expect.objectContaining({ + markdown: expect.objectContaining({mdx1Compat}), + }); + } + + const MDX1_COMPAT_ALL_TRUE = { + comments: true, + admonitions: true, + headingIds: true, + }; + + const MDX1_COMPAT_ALL_FALSE = { + comments: false, + admonitions: false, + headingIds: false, + }; + + it('defaults mdx1Compat to all true when flag is off', () => { + expect(normalizeConfig({})).toEqual( + mdx1CompatContaining(MDX1_COMPAT_ALL_TRUE), + ); + }); + + it('defaults mdx1Compat to all false when flag is on', () => { + expect( + normalizeConfig({ + future: {v4: {mdx1CompatDisabledByDefault: true}}, + }), + ).toEqual(mdx1CompatContaining(MDX1_COMPAT_ALL_FALSE)); + }); + + it('defaults mdx1Compat to all false when v4: true', () => { + expect( + normalizeConfig({ + future: {v4: true}, + }), + ).toEqual(mdx1CompatContaining(MDX1_COMPAT_ALL_FALSE)); + }); + + it('keeps explicit mdx1Compat overrides when flag is on', () => { + expect( + normalizeConfig({ + future: {v4: {mdx1CompatDisabledByDefault: true}}, + markdown: { + mdx1Compat: {admonitions: true}, + }, + }), + ).toEqual( + mdx1CompatContaining({ + comments: false, + admonitions: true, + headingIds: false, + }), + ); + }); + }); }); }); diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 5558b509ca75..ca52e6264b44 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -26,6 +26,7 @@ import type { FutureV4Config, I18nConfig, I18nLocaleConfig, + MDX1CompatOptions, MarkdownConfig, MarkdownHooks, StorageConfig, @@ -102,6 +103,7 @@ export const DEFAULT_FUTURE_V4_CONFIG: FutureV4Config = { useCssCascadeLayers: false, siteStorageNamespacing: false, fasterByDefault: false, + mdx1CompatDisabledByDefault: false, }; // When using the "v4: true" shortcut @@ -110,6 +112,7 @@ export const DEFAULT_FUTURE_V4_CONFIG_TRUE: FutureV4Config = { useCssCascadeLayers: true, siteStorageNamespacing: true, fasterByDefault: true, + mdx1CompatDisabledByDefault: true, }; export const DEFAULT_FUTURE_CONFIG: FutureConfig = { @@ -130,11 +133,10 @@ export const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig = { emoji: true, preprocessor: undefined, parseFrontMatter: DEFAULT_PARSE_FRONT_MATTER, - mdx1Compat: { - comments: true, - admonitions: true, - headingIds: true, - }, + // Individual mdx1Compat boolean defaults are not set here on purpose + // They are resolved in postProcessDocusaurusConfig based on + // the future.v4.mdx1CompatDisabledByDefault flag + mdx1Compat: {} as MDX1CompatOptions, anchors: { maintainCase: false, }, @@ -319,6 +321,9 @@ const FUTURE_V4_SCHEMA = Joi.alternatives() fasterByDefault: Joi.boolean().default( DEFAULT_FUTURE_V4_CONFIG.fasterByDefault, ), + mdx1CompatDisabledByDefault: Joi.boolean().default( + DEFAULT_FUTURE_V4_CONFIG.mdx1CompatDisabledByDefault, + ), }), Joi.boolean() .required() @@ -511,17 +516,14 @@ export const ConfigSchema = Joi.object({ .arity(1) .optional() .default(() => DEFAULT_CONFIG.markdown.preprocessor), + // Individual boolean defaults are not set here on purpose + // They are resolved in postProcessDocusaurusConfig based on + // the future.v4.mdx1CompatDisabledByDefault flag mdx1Compat: Joi.object({ - comments: Joi.boolean().default( - DEFAULT_CONFIG.markdown.mdx1Compat.comments, - ), - admonitions: Joi.boolean().default( - DEFAULT_CONFIG.markdown.mdx1Compat.admonitions, - ), - headingIds: Joi.boolean().default( - DEFAULT_CONFIG.markdown.mdx1Compat.headingIds, - ), - }).default(DEFAULT_CONFIG.markdown.mdx1Compat), + comments: Joi.boolean(), + admonitions: Joi.boolean(), + headingIds: Joi.boolean(), + }).default({}), remarkRehypeOptions: // add proper external options validation? // Not sure if it's a good idea, validation is likely to become stale @@ -576,6 +578,18 @@ function postProcessDocusaurusConfig(config: DocusaurusConfig) { } } + // Resolve mdx1Compat config based on the v4.mdx1CompatDisabledByDefault flag + // undefined means "not explicitly set by user" + const mdx1CompatDefault = !config.future.v4.mdx1CompatDisabledByDefault; + const mdx1CompatKeys: (keyof MDX1CompatOptions)[] = [ + 'comments', + 'admonitions', + 'headingIds', + ]; + for (const key of mdx1CompatKeys) { + config.markdown.mdx1Compat[key] ??= mdx1CompatDefault; + } + if (config.onBrokenMarkdownLinks) { logger.warn`The code=${'siteConfig.onBrokenMarkdownLinks'} config option is deprecated and will be removed in Docusaurus v4. Please migrate and move this option to code=${'siteConfig.markdown.hooks.onBrokenMarkdownLinks'} instead.`; diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index e0477b74bc17..a030c23f2bff 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -234,8 +234,7 @@ export default async function createConfigAsync() { onBrokenMarkdownLinks: 'warn', }, mdx1Compat: { - headingIds: false, - comments: false, + admonitions: true, }, remarkRehypeOptions: { footnoteLabel: getLocalizedConfigValue('remarkRehypeOptions_footnotes'), From a94d46018dbe5c570fb9d6f71221975e41f8fcef Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 17:06:43 +0200 Subject: [PATCH 2/6] docs --- website/docs/api/docusaurus.config.js.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/docs/api/docusaurus.config.js.mdx b/website/docs/api/docusaurus.config.js.mdx index 8e0019f461aa..f1547f79aef0 100644 --- a/website/docs/api/docusaurus.config.js.mdx +++ b/website/docs/api/docusaurus.config.js.mdx @@ -254,6 +254,7 @@ export default { useCssCascadeLayers: true, siteStorageNamespacing: true, fasterByDefault: true, + mdx1CompatDisabledByDefault: true, }, faster: { swcJsLoader: true, @@ -275,6 +276,7 @@ export default { - [`useCssCascadeLayers`](https://github.com/facebook/docusaurus/pull/11142): This enables the [Docusaurus CSS Cascade Layers plugin](./plugins/plugin-css-cascade-layers.mdx) with pre-configured layers that we plan to apply by default for Docusaurus v4. - `siteStorageNamespacing`: Defaults the [`storage.namespace`](#storage) config to `true` instead of `false`. This enables automatic browser storage key namespacing, which avoids storage key conflicts when multiple Docusaurus sites are hosted under the same domain, or on localhost. - `fasterByDefault`: Defaults all `future.faster` flags to `true` instead of `false`. This enables [Docusaurus Faster](https://github.com/facebook/docusaurus/issues/10556) features by default. Requires having `@docusaurus/faster` in your dependencies. If you explicitly set individual `faster` flags, those explicit values take precedence. + - `mdx1CompatDisabledByDefault`: Defaults all [`markdown.mdx1Compat`](#markdown) flags to `false` instead of `true`. This prepares your site for Docusaurus v4, which will not enable MDX v1 compatibility by default. If you explicitly set individual `mdx1Compat` flags, those explicit values take precedence. - `faster`: An object containing feature flags to make the Docusaurus build faster. This requires adding the `@docusaurus/faster` package to your site's dependencies. Use `true` as a shorthand to enable all flags. Read more on the [Docusaurus Faster](https://github.com/facebook/docusaurus/issues/10556) issue. Available feature flags: - [`swcJsLoader`](https://github.com/facebook/docusaurus/pull/10435): Use [SWC](https://swc.rs/) to transpile JS (instead of [Babel](https://babeljs.io/)). - [`swcJsMinimizer`](https://github.com/facebook/docusaurus/pull/10441): Use [SWC](https://swc.rs/) to minify JS (instead of [Terser](https://github.com/terser/terser)). @@ -734,7 +736,7 @@ export default { | `emoji` | `boolean` | `true` | When `true`, allows Docusaurus to render emoji shortcodes (e.g., `:+1:`) as Unicode emoji (👍). When `false`, emoji shortcodes are left as-is. | | `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. | | `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. | -| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. | +| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. Defaults to all `false` when [`future.v4.mdx1CompatDisabledByDefault`](#future) is enabled. | | `anchors` | `MarkdownAnchorsConfig` | `{maintainCase: false}` | Options to control the behavior of anchors generated from Markdown headings | | `remarkRehypeOptions` | `object` | `undefined` | Makes it possible to pass custom [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#options). | | `hooks` | `MarkdownHooks` | `object` | Make it possible to customize the MDX loader behavior with callbacks or built-in options. | From a484c0c7a19841f3d0da0ef049d8443f96d7181f Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 17:07:52 +0200 Subject: [PATCH 3/6] update snapshots --- .../__tests__/__snapshots__/config.test.ts.snap | 10 ++++++++++ .../server/__tests__/__snapshots__/site.test.ts.snap | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap index c0437a9e133a..35701f702613 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap @@ -27,6 +27,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -114,6 +115,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -201,6 +203,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -288,6 +291,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -375,6 +379,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -462,6 +467,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -549,6 +555,7 @@ exports[`loadSiteConfig website with valid async config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -638,6 +645,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -727,6 +735,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -819,6 +828,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap index a6999ad02ad6..d10c593e052c 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap @@ -107,6 +107,7 @@ exports[`loadSite custom-i18n-site loads site 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -282,6 +283,7 @@ exports[`loadSite simple-site-with-baseUrl loads site - custom config 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -449,6 +451,7 @@ exports[`loadSite simple-site-with-baseUrl loads site - custom outDir 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -616,6 +619,7 @@ exports[`loadSite simple-site-with-baseUrl loads site 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -827,6 +831,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale fr + custom }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -1060,6 +1065,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - custom outDir 1`] = }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -1293,6 +1299,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale de 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -1526,6 +1533,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale en 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -1759,6 +1767,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale es 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -1992,6 +2001,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale fr 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -2225,6 +2235,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site - locale it 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, @@ -2458,6 +2469,7 @@ exports[`loadSite simple-site-with-baseUrl-i18n loads site 1`] = ` }, "v4": { "fasterByDefault": false, + "mdx1CompatDisabledByDefault": false, "removeLegacyPostBuildHeadAttribute": false, "siteStorageNamespacing": false, "useCssCascadeLayers": false, From 0debca11f3f4c98818d6918524c13f849b929f65 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 18:25:34 +0200 Subject: [PATCH 4/6] add crowdin comment --- website/docusaurus.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index a030c23f2bff..7246fcc3266e 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -234,6 +234,8 @@ export default async function createConfigAsync() { onBrokenMarkdownLinks: 'warn', }, mdx1Compat: { + // Needed for us until Crowdin improves support + // See https://github.com/facebook/docusaurus/pull/11847#issuecomment-4183213345 admonitions: true, }, remarkRehypeOptions: { From 5050fd7832702fc39daa6e13655794790ff75e2e Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 18:42:15 +0200 Subject: [PATCH 5/6] improve tests --- .../server/__tests__/configValidation.test.ts | 30 +++--------------- .../docusaurus/src/server/configValidation.ts | 31 ++++++++++++------- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index b97df9814d40..b2364c80ce70 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -44,26 +44,12 @@ const baseConfig = { const normalizeConfig = (config: DeepPartial): DocusaurusConfig => validateConfig({...baseConfig, ...config}, 'docusaurus.config.js'); -// mdx1Compat defaults are resolved in postProcessDocusaurusConfig -// based on the future.v4.mdx1CompatDisabledByDefault flag -// DEFAULT_CONFIG.markdown.mdx1Compat is {} (unresolved) -// This is the resolved version when the flag is off (default) -const DEFAULT_MDX1_COMPAT_RESOLVED = { - comments: true, - admonitions: true, - headingIds: true, -}; - describe('normalizeConfig', () => { it('normalizes empty config', () => { const value = normalizeConfig({markdown: {}}); expect(value).toEqual({ ...DEFAULT_CONFIG, ...baseConfig, - markdown: { - ...DEFAULT_CONFIG.markdown, - mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, - }, }); }); @@ -161,10 +147,6 @@ describe('normalizeConfig', () => { expect(value).toEqual({ ...DEFAULT_CONFIG, ...baseConfig, - markdown: { - ...DEFAULT_CONFIG.markdown, - mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, - }, customFields: { author: 'anshul', }, @@ -532,17 +514,13 @@ describe('markdown', () => { ): MarkdownConfig { return normalizeConfig({markdown}).markdown; } - const DEFAULT_MARKDOWN_RESOLVED = { - ...DEFAULT_CONFIG.markdown, - mdx1Compat: DEFAULT_MDX1_COMPAT_RESOLVED, - }; it('accepts undefined object', () => { - expect(normalizeMarkdown(undefined)).toEqual(DEFAULT_MARKDOWN_RESOLVED); + expect(normalizeMarkdown(undefined)).toEqual(DEFAULT_CONFIG.markdown); }); it('accepts empty object', () => { - expect(normalizeMarkdown({})).toEqual(DEFAULT_MARKDOWN_RESOLVED); + expect(normalizeMarkdown({})).toEqual(DEFAULT_CONFIG.markdown); }); it('accepts valid markdown object', () => { @@ -582,10 +560,10 @@ describe('markdown', () => { }, }; expect(normalizeMarkdown(markdown)).toEqual({ - ...DEFAULT_MARKDOWN_RESOLVED, + ...DEFAULT_CONFIG.markdown, ...markdown, mdx1Compat: { - ...DEFAULT_MDX1_COMPAT_RESOLVED, + comments: true, ...markdown.mdx1Compat, }, }); diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index ca52e6264b44..724f4ea70cf2 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -127,16 +127,22 @@ export const DEFAULT_MARKDOWN_HOOKS: MarkdownHooks = { onBrokenMarkdownImages: 'throw', }; +export const DEFAULT_MARKDOWN_MDX1COMPAT: MDX1CompatOptions = { + comments: true, + admonitions: true, + headingIds: true, +}; + export const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig = { - format: 'mdx', // TODO change this to "detect" in Docusaurus v4? + // TODO Docusaurus v5: change this to "detect"? + // we probably need stable CommonMark support first + // see https://github.com/facebook/docusaurus/issues/9092 + format: 'mdx', mermaid: false, emoji: true, preprocessor: undefined, parseFrontMatter: DEFAULT_PARSE_FRONT_MATTER, - // Individual mdx1Compat boolean defaults are not set here on purpose - // They are resolved in postProcessDocusaurusConfig based on - // the future.v4.mdx1CompatDisabledByDefault flag - mdx1Compat: {} as MDX1CompatOptions, + mdx1Compat: DEFAULT_MARKDOWN_MDX1COMPAT, anchors: { maintainCase: false, }, @@ -548,7 +554,12 @@ export const ConfigSchema = Joi.object({ ) .default(DEFAULT_CONFIG.markdown.hooks.onBrokenMarkdownImages), }).default(DEFAULT_CONFIG.markdown.hooks), - }).default(DEFAULT_CONFIG.markdown), + }).default({ + ...DEFAULT_CONFIG.markdown, + mdx1Compat: { + // erased on purpose, filled using postprocessing + }, + }), }).messages({ 'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}', @@ -581,11 +592,9 @@ function postProcessDocusaurusConfig(config: DocusaurusConfig) { // Resolve mdx1Compat config based on the v4.mdx1CompatDisabledByDefault flag // undefined means "not explicitly set by user" const mdx1CompatDefault = !config.future.v4.mdx1CompatDisabledByDefault; - const mdx1CompatKeys: (keyof MDX1CompatOptions)[] = [ - 'comments', - 'admonitions', - 'headingIds', - ]; + const mdx1CompatKeys = Object.keys( + DEFAULT_MARKDOWN_MDX1COMPAT, + ) as (keyof MDX1CompatOptions)[]; for (const key of mdx1CompatKeys) { config.markdown.mdx1Compat[key] ??= mdx1CompatDefault; } From cc993ed1722a560034cdb7d08b6803da7df7113a Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 3 Apr 2026 18:44:41 +0200 Subject: [PATCH 6/6] improve tests --- .../docusaurus/src/server/__tests__/configValidation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index b2364c80ce70..6ed937c2a31d 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -563,7 +563,7 @@ describe('markdown', () => { ...DEFAULT_CONFIG.markdown, ...markdown, mdx1Compat: { - comments: true, + ...DEFAULT_CONFIG.markdown.mdx1Compat, ...markdown.mdx1Compat, }, });