feat: Markdown page-specific head metadatas (#5330)

* Markdown page-specific head metadatas

* ensure mdxType attribute is not added to the final markup

* polish doc

* Update packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>

* fix eslint annoying rule error

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Sébastien Lorber 2021-08-11 11:39:01 +02:00 committed by GitHub
parent 6c21061e34
commit a2ab4d33c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 1 deletions

View file

@ -93,7 +93,10 @@ module.exports = {
'no-nested-ternary': WARNING,
'@typescript-eslint/no-empty-function': OFF,
'@typescript-eslint/no-non-null-assertion': OFF, // Have to use type assertion anyways
'@typescript-eslint/no-unused-vars': [ERROR, {argsIgnorePattern: '^_'}],
'@typescript-eslint/no-unused-vars': [
ERROR,
{argsIgnorePattern: '^_', ignoreRestSiblings: true},
],
'@typescript-eslint/ban-ts-comment': [
ERROR,
{'ts-expect-error': 'allow-with-description'},

View file

@ -6,13 +6,30 @@
*/
import React, {ComponentProps, isValidElement, ReactElement} from 'react';
import Head from '@docusaurus/Head';
import Link from '@docusaurus/Link';
import CodeBlock, {Props} from '@theme/CodeBlock';
import Heading from '@theme/Heading';
import Details from '@theme/Details';
import type {MDXComponentsObject} from '@theme/MDXComponents';
// MDX elements are wrapped through the MDX pragma
// In some cases (notably usage with Head/Helmet) we need to unwrap those elements.
function unwrapMDXElement(element: ReactElement) {
if (element?.props?.mdxType && element?.props?.originalType) {
const {mdxType, originalType, ...newProps} = element.props;
return React.createElement(element.props.originalType, newProps);
}
return element;
}
const MDXComponents: MDXComponentsObject = {
head: (props) => {
const unwrappedChildren = React.Children.map(props.children, (child) =>
unwrapMDXElement(child as ReactElement),
);
return <Head {...props}>{unwrappedChildren}</Head>;
},
code: (props) => {
const {children} = props;

View file

@ -351,8 +351,10 @@ declare module '@theme/SkipToContent' {
declare module '@theme/MDXComponents' {
import type {ComponentProps} from 'react';
import type CodeBlock from '@theme/CodeBlock';
import type Head from '@docusaurus/Head';
export type MDXComponentsObject = {
readonly head: typeof Head;
readonly code: typeof CodeBlock;
readonly a: (props: ComponentProps<'a'>) => JSX.Element;
readonly pre: typeof CodeBlock;

View file

@ -0,0 +1,61 @@
---
id: head-metadatas
title: Head Metadatas
description: Declaring page-specific head metadatas through MDX
slug: /markdown-features/head-metadatas
---
# Head Metadatas
Docusaurus automatically sets useful page metadatas in `<html>`, `<head>` and `<body>` for you.
It is possible to add extra metadatas (or override existing ones) by using the `<head>` tag in Markdown files:
```md title="markdown-features-head-metadatas.mdx"
---
id: head-metadatas
title: Head Metadatas
---
<!-- highlight-start -->
<head>
<html className="some-extra-html-class" />
<body className="other-extra-body-class" />
<title>Head Metadatas customized title!</title>
<meta charSet="utf-8" />
<meta name="twitter:card" content="summary" />
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadatas" />
</head>
<!-- highlight-end -->
# Head Metadatas
My text
```
```mdx-code-block
<head>
<html className="some-extra-html-class" />
<body className="other-extra-body-class" />
<title>Head Metadatas customized title!</title>
<meta charSet="utf-8" />
<meta name="twitter:card" content="summary" />
<link rel="canonical" href="https://docusaurus.io/docs/markdown-features/head-metadatas" />
</head>
```
:::tip
This `<head>` declaration has been added to the current Markdown doc, as a demo.
Open your browser DevTools and check how this page's metadatas have been affected.
:::
:::note
This feature is built on top of the Docusaurus [`<Head>`](./../../docusaurus-core.md#head) component.
Refer to [react-helmet](https://github.com/nfl/react-helmet) for exhaustive documentation.
:::

View file

@ -49,6 +49,7 @@ module.exports = {
'guides/markdown-features/assets',
'guides/markdown-features/plugins',
'guides/markdown-features/math-equations',
'guides/markdown-features/head-metadatas',
],
},
'styling-layout',