diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
index c4d51f69ef..accafb0f96 100644
--- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts
+++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
@@ -114,6 +114,7 @@ declare module '@theme/CodeBlock' {
readonly className?: string;
readonly metastring?: string;
readonly title?: string;
+ readonly language?: string;
}
const CodeBlock: (props: Props) => JSX.Element;
diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx
index bab753c075..8ae921488d 100644
--- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx
@@ -24,9 +24,10 @@ import styles from './styles.module.css';
export default function CodeBlock({
children,
- className: blockClassName,
+ className: blockClassName = '',
metastring,
title,
+ language: languageProp,
}: Props): JSX.Element {
const {prism} = useThemeConfig();
@@ -85,8 +86,7 @@ export default function CodeBlock({
: (children as string);
const language =
- parseLanguage(blockClassName) ??
- (prism.defaultLanguage as Language | undefined);
+ languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
const {highlightLines, code} = parseLines(content, metastring, language);
const handleCopyCode = () => {
@@ -102,12 +102,16 @@ export default function CodeBlock({
key={String(mounted)}
theme={prismTheme}
code={code}
- language={language ?? ('text' as Language)}>
+ language={(language ?? 'text') as Language}>
{({className, style, tokens, getLineProps, getTokenProps}) => (
{codeBlockTitle && (
diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts
index 77833da6e9..a279afc5fd 100644
--- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts
+++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts
@@ -6,7 +6,6 @@
*/
import rangeParser from 'parse-numeric-range';
-import type {Language} from 'prism-react-renderer';
const codeBlockTitleRegex = /title=(["'])(.*?)\1/;
const highlightLinesRangeRegex = /{([\d,-]+)}/;
@@ -93,11 +92,11 @@ export function parseCodeBlockTitle(metastring?: string): string {
return metastring?.match(codeBlockTitleRegex)?.[2] ?? '';
}
-export function parseLanguage(className?: string): Language | undefined {
+export function parseLanguage(className: string): string | undefined {
const languageClassName = className
- ?.split(' ')
+ .split(' ')
.find((str) => str.startsWith('language-'));
- return languageClassName?.replace(/language-/, '') as Language | undefined;
+ return languageClassName?.replace(/language-/, '');
}
/**
@@ -107,7 +106,7 @@ export function parseLanguage(className?: string): Language | undefined {
export function parseLines(
content: string,
metastring?: string,
- language?: Language,
+ language?: string,
): {
highlightLines: number[];
code: string;
diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx
index c362434897..d3638dd7ba 100644
--- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx
+++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx
@@ -6,6 +6,7 @@ slug: /markdown-features/code-blocks
---
import BrowserWindow from '@site/src/components/BrowserWindow';
+import CodeBlock from '@theme/CodeBlock';
Code blocks within documentation are super-powered 💪.
@@ -391,7 +392,7 @@ function MyPlayground(props) {
-## Using JSX markup in code blocks
+## Using JSX markup in code blocks {using-jsx-markup}
Code block in Markdown always preserves its content as plain text, meaning you can't do something like:
@@ -564,3 +565,39 @@ npm install @docusaurus/remark-plugin-npm2yarn
````
Using the `{sync: true}` option would make all tab choices synced. Because the choice is stored under the same namespace `npm2yarn`, different `npm2yarn` plugin instances would also sync their choices.
+
+## Usage in JSX {#usage-in-jsx}
+
+Outside of Markdown, you can use the `@theme/CodeBlock` component to get the same output.
+
+```jsx
+import CodeBlock from '@theme/CodeBlock';
+
+export default function MyReactPage() {
+ return (
+
+ {/* highlight-start */}
+
+ {`function HelloCodeTitle(props) {
+ return Hello, {props.name}
;
+}`}
+
+ {/* highlight-end */}
+
+ );
+}
+```
+
+
+
+ {`function HelloCodeTitle(props) {
+ return Hello, {props.name}
;
+}`}
+
+
+
+The props accepted are `language` and `title`, in the same way as you write Markdown code blocks.
+
+Although discouraged, you can also pass in a `metastring` prop like `metastring='{1-2} title="/src/components/HelloCodeTitle.js"'`, which is how Markdown code blocks are handled under the hood. However, we recommend you [use comments for highlighting lines](#highlighting-with-comments).
+
+As [previously stated](#using-jsx-markup), syntax highlighting is only applied when the children is a simple string.
diff --git a/website/docs/guides/markdown-features/markdown-features-react.mdx b/website/docs/guides/markdown-features/markdown-features-react.mdx
index 4fcc5ae9ff..36108adce8 100644
--- a/website/docs/guides/markdown-features/markdown-features-react.mdx
+++ b/website/docs/guides/markdown-features/markdown-features-react.mdx
@@ -116,17 +116,11 @@ import MyComponentSource from '!!raw-loader!@site/src/pages/examples/_myComponen
```
-You can also pass `title` prop to `CodeBlock` component in order for it to appear as header above your code block:
-
-```jsx
-
- {MyComponentSource}
-
-```
+See [using code blocks in JSX](./markdown-features-code-blocks.mdx#usage-in-jsx) for more details of the `
` component.
:::note
-You have to use `` rather than the Markdown triple-backtick ` ``` `, because the latter will ship out any of its content as-is, but you want JSX to insert the imported text here.
+You have to use `` rather than the Markdown triple-backtick ` ``` `, because the latter will ship out any of its content as-is, but you want to interpolate the imported text here.
:::