Skip to content

Commit 05e93a1

Browse files
committed
feat(core): add siteConfig.markdown.emoji config option to disable remark-emoji (#11282)
1 parent 04eca29 commit 05e93a1

7 files changed

Lines changed: 87 additions & 9 deletions

File tree

packages/docusaurus-mdx-loader/src/processor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async function createProcessorFactory() {
9595
headings,
9696
{anchorsMaintainCase: options.markdownConfig.anchors.maintainCase},
9797
],
98-
emoji,
98+
...(options.markdownConfig.emoji ? [emoji] : []),
9999
toc,
100100
];
101101
}

packages/docusaurus-types/src/markdown.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ export type MarkdownConfig = {
136136
*/
137137
mermaid: boolean;
138138

139+
/**
140+
* Allow remark-emoji to convert emoji shortcodes to Unicode emoji.
141+
* - `true` (default): enables the remark-emoji plugin to convert shortcodes
142+
* - `false`: disables the remark-emoji plugin
143+
*
144+
* @see https://github.com/rhysd/remark-emoji
145+
* @default true
146+
*/
147+
emoji: boolean;
148+
139149
/**
140150
* Gives opportunity to preprocess the MDX string content before compiling.
141151
* A good escape hatch that can be used to handle edge cases.

packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
4141
"anchors": {
4242
"maintainCase": false,
4343
},
44+
"emoji": true,
4445
"format": "mdx",
4546
"hooks": {
4647
"onBrokenMarkdownImages": "throw",
@@ -119,6 +120,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
119120
"anchors": {
120121
"maintainCase": false,
121122
},
123+
"emoji": true,
122124
"format": "mdx",
123125
"hooks": {
124126
"onBrokenMarkdownImages": "throw",
@@ -197,6 +199,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
197199
"anchors": {
198200
"maintainCase": false,
199201
},
202+
"emoji": true,
200203
"format": "mdx",
201204
"hooks": {
202205
"onBrokenMarkdownImages": "throw",
@@ -275,6 +278,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
275278
"anchors": {
276279
"maintainCase": false,
277280
},
281+
"emoji": true,
278282
"format": "mdx",
279283
"hooks": {
280284
"onBrokenMarkdownImages": "throw",
@@ -353,6 +357,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
353357
"anchors": {
354358
"maintainCase": false,
355359
},
360+
"emoji": true,
356361
"format": "mdx",
357362
"hooks": {
358363
"onBrokenMarkdownImages": "throw",
@@ -431,6 +436,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
431436
"anchors": {
432437
"maintainCase": false,
433438
},
439+
"emoji": true,
434440
"format": "mdx",
435441
"hooks": {
436442
"onBrokenMarkdownImages": "throw",
@@ -509,6 +515,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
509515
"anchors": {
510516
"maintainCase": false,
511517
},
518+
"emoji": true,
512519
"format": "mdx",
513520
"hooks": {
514521
"onBrokenMarkdownImages": "throw",
@@ -589,6 +596,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
589596
"anchors": {
590597
"maintainCase": false,
591598
},
599+
"emoji": true,
592600
"format": "mdx",
593601
"hooks": {
594602
"onBrokenMarkdownImages": "throw",
@@ -669,6 +677,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
669677
"anchors": {
670678
"maintainCase": false,
671679
},
680+
"emoji": true,
672681
"format": "mdx",
673682
"hooks": {
674683
"onBrokenMarkdownImages": "throw",
@@ -752,6 +761,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
752761
"anchors": {
753762
"maintainCase": false,
754763
},
764+
"emoji": true,
755765
"format": "mdx",
756766
"hooks": {
757767
"onBrokenMarkdownImages": "throw",

packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
125125
"anchors": {
126126
"maintainCase": false,
127127
},
128+
"emoji": true,
128129
"format": "mdx",
129130
"hooks": {
130131
"onBrokenMarkdownImages": "throw",

packages/docusaurus/src/server/__tests__/configValidation.test.ts

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ import {
1717
DEFAULT_STORAGE_CONFIG,
1818
validateConfig,
1919
} from '../configValidation';
20-
import type {
21-
MarkdownConfig,
22-
MarkdownHooks,
23-
} from '@docusaurus/types/src/markdown';
2420
import type {
2521
FasterConfig,
2622
FutureConfig,
2723
FutureV4Config,
2824
StorageConfig,
29-
} from '@docusaurus/types/src/config';
30-
import type {Config, DocusaurusConfig, PluginConfig} from '@docusaurus/types';
25+
MarkdownConfig,
26+
MarkdownHooks,
27+
Config,
28+
DocusaurusConfig,
29+
PluginConfig,
30+
} from '@docusaurus/types';
3131
import type {DeepPartial} from 'utility-types';
3232

3333
const baseConfig = {
@@ -36,7 +36,7 @@ const baseConfig = {
3636
url: 'https://mysite.com',
3737
} as Config;
3838

39-
const normalizeConfig = (config: DeepPartial<Config>) =>
39+
const normalizeConfig = (config: DeepPartial<Config>): DocusaurusConfig =>
4040
validateConfig({...baseConfig, ...config}, 'docusaurus.config.js');
4141

4242
describe('normalizeConfig', () => {
@@ -99,6 +99,7 @@ describe('normalizeConfig', () => {
9999
markdown: {
100100
format: 'md',
101101
mermaid: true,
102+
emoji: false,
102103
parseFrontMatter: async (params) =>
103104
params.defaultParseFrontMatter(params),
104105
preprocessor: ({fileContent}) => fileContent,
@@ -366,7 +367,9 @@ describe('onBrokenLinks', () => {
366367
});
367368

368369
describe('markdown', () => {
369-
function normalizeMarkdown(markdown: DeepPartial<MarkdownConfig>) {
370+
function normalizeMarkdown(
371+
markdown: DeepPartial<MarkdownConfig>,
372+
): MarkdownConfig {
370373
return normalizeConfig({markdown}).markdown;
371374
}
372375
it('accepts undefined object', () => {
@@ -381,6 +384,7 @@ describe('markdown', () => {
381384
const markdown: Config['markdown'] = {
382385
format: 'md',
383386
mermaid: true,
387+
emoji: false,
384388
parseFrontMatter: async (params) =>
385389
params.defaultParseFrontMatter(params),
386390
preprocessor: ({fileContent}) => fileContent,
@@ -476,6 +480,54 @@ describe('markdown', () => {
476480
`);
477481
});
478482

483+
describe('emoji', () => {
484+
it('accepts emoji boolean true', () => {
485+
expect(
486+
normalizeMarkdown({
487+
emoji: true,
488+
}).emoji,
489+
).toBe(true);
490+
});
491+
492+
it('accepts emoji boolean false', () => {
493+
expect(
494+
normalizeMarkdown({
495+
emoji: false,
496+
}).emoji,
497+
).toBe(false);
498+
});
499+
500+
it('defaults emoji to true when undefined', () => {
501+
expect(normalizeMarkdown({}).emoji).toBe(true);
502+
});
503+
504+
it('throw for string emoji value', () => {
505+
expect(() =>
506+
normalizeMarkdown({
507+
// @ts-expect-error: bad value
508+
emoji: 'yes',
509+
}),
510+
).toThrowErrorMatchingInlineSnapshot(`
511+
""markdown.emoji" must be a boolean
512+
"
513+
`);
514+
});
515+
516+
it('throw for number emoji value', () => {
517+
expect(() =>
518+
normalizeConfig({
519+
markdown: {
520+
// @ts-expect-error: bad value
521+
emoji: 1,
522+
},
523+
}),
524+
).toThrowErrorMatchingInlineSnapshot(`
525+
""markdown.emoji" must be a boolean
526+
"
527+
`);
528+
});
529+
});
530+
479531
describe('hooks', () => {
480532
function normalizeHooks(hooks: DeepPartial<MarkdownHooks>): MarkdownHooks {
481533
return normalizeMarkdown({

packages/docusaurus/src/server/configValidation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const DEFAULT_MARKDOWN_HOOKS: MarkdownHooks = {
9191
export const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig = {
9292
format: 'mdx', // TODO change this to "detect" in Docusaurus v4?
9393
mermaid: false,
94+
emoji: true,
9495
preprocessor: undefined,
9596
parseFrontMatter: DEFAULT_PARSE_FRONT_MATTER,
9697
mdx1Compat: {
@@ -435,6 +436,7 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
435436
() => DEFAULT_CONFIG.markdown.parseFrontMatter,
436437
),
437438
mermaid: Joi.boolean().default(DEFAULT_CONFIG.markdown.mermaid),
439+
emoji: Joi.boolean().default(DEFAULT_CONFIG.markdown.emoji),
438440
preprocessor: Joi.function()
439441
.arity(1)
440442
.optional()

website/docs/api/docusaurus.config.js.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ type MarkdownHooks = {
541541
type MarkdownConfig = {
542542
format: 'mdx' | 'md' | 'detect';
543543
mermaid: boolean;
544+
emoji: boolean;
544545
preprocessor?: MarkdownPreprocessor;
545546
parseFrontMatter?: ParseFrontMatter;
546547
mdx1Compat: MDX1CompatOptions;
@@ -557,6 +558,7 @@ export default {
557558
markdown: {
558559
format: 'mdx',
559560
mermaid: true,
561+
emoji: true,
560562
preprocessor: ({filePath, fileContent}) => {
561563
return fileContent.replaceAll('{{MY_VAR}}', 'MY_VALUE');
562564
},
@@ -590,6 +592,7 @@ export default {
590592
| --- | --- | --- | --- |
591593
| `format` | `'mdx' \| 'md' \| 'detect'` | `'mdx'` | The default parser format to use for Markdown content. Using 'detect' will select the appropriate format automatically based on file extensions: `.md` vs `.mdx`. |
592594
| `mermaid` | `boolean` | `false` | When `true`, allows Docusaurus to render Markdown code blocks with `mermaid` language as Mermaid diagrams. |
595+
| `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. |
593596
| `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. |
594597
| `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. |
595598
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. |

0 commit comments

Comments
 (0)