docusaurus icon indicating copy to clipboard operation
docusaurus copied to clipboard

Make most features work in CommonMark mode: head, live code blocks, tabs...

Open slorber opened this issue 2 years ago • 9 comments

Motivation

Related to the CommonMark support issue: https://github.com/facebook/docusaurus/issues/3018

Some custom elements we created do not work when using the CommonMark parser mode, that you can turn on using:

  • frontMatter.mdx.format: 'md'
  • config.markdown.format: 'detect' + using the .md extension

I think it would be convenient for users to have features working fine in both modes in a consistent way. I believe it is possible, but may require some adaptations.

Here are some components that do not currently work:


SEO

This should work in CommonMark too, but currently does not:

<head>
  <title>HEAD Markdown Page tests title</title>
  <meta name="keywords" content="cooking, blog">
</head>

Summary/details

Renders as:

CleanShot 2023-06-22 at 17 06 05

Instead of:

CleanShot 2023-06-22 at 17 07 11


Live code editor

Renders as:

CleanShot 2023-06-22 at 17 07 58

Instead of:

CleanShot 2023-06-22 at 17 07 28


Tabs

Renders as: N/A because we don't have any syntax that does not require using MDX/ESM imports.

Instead of:

CleanShot 2023-06-22 at 17 08 35

Possible solution? IMHO this syntax should be allowed without imports:

<tabs>
  <tabItem value="apple" label="Apple" default>
    This is an apple 🍎
  </tabItem>
  <tabItem value="orange" label="Orange">
    This is an orange 🍊
  </tabItem>
  <tabItem value="banana" label="Banana">
    This is a banana 🍌
  </tabItem>
</tabs>

Structured data

As part of https://github.com/facebook/docusaurus/pull/9669 we are adding a @theme/StructuredData helper component:

import StructuredData from "@theme/StructuredData";

<head>
  <meta name="keywords" content="cooking, blog" />
  <meta name="twitter:card" content="summary_large_image" />
  <link rel="preconnect" href="https://example.com" />
  <StructuredData structuredData={{
    '@context': 'https://schema.org/',
    '@type': 'Organization',
    name: 'Meta Open Source',
    url: 'https://opensource.fb.com/',
    logo: 'https://opensource.fb.com/img/logos/Meta-Open-Source.svg',
  }} />
</head>

# Title

We should figure out how to define structured data in CommonMark mode

Self-service

  • [X] I'd be willing to do some initial work on this proposal myself.

slorber avatar Jun 22 '23 15:06 slorber

Is my understanding correct that CommonMark mode does not allow providing custom components at all? If so, do we need to walk the React element tree created by mdx-loader in client code so we can inject our React components?

It seems rather imperative for us to make <details> and live code blocks work, but I'm not sure about tabs, considering we've always advocated them as an MDX-special feature, and people migrating from legacy (non-Docusaurus2) systems aren't likely going to use them anyway.

Josh-Cena avatar Jun 22 '23 15:06 Josh-Cena

Is my understanding correct that CommonMark mode does not allow providing custom components at all?

It does not allow the usage of JSX when parsing the input, but it still compiles to React components, and you can process the AST so that it outputs what you want, reading components from the provider.

I recently added a few useful options to the MDX playground to make this easier to understand.

CleanShot 2023-06-22 at 17 19 35

Note: when using the lowercase <summary>, the MDX rehype serializer output will not "read from the MDXProvider". To do so, we'd just have to capitalize it, and the output would then read from the MDXProvider and use the appropriate theme component.


What I mean is technically nothing prevents of from offering a feature parity for most of these features, so if we can, why not!

slorber avatar Jun 22 '23 15:06 slorber

Hmmm my mistake, with CommonMark mode even lowercase elements seem to be able to read from the provider:

function _createMdxContent(props) {
  const _components = Object.assign({
    details: "details",
    summary: "summary",
    p: "p"
  }, props.components);
  return _jsxs(_components.details, {
    children: ["\n  ", _jsx(_components.summary, {
      children: "MD Summary"
    }), "\n", _jsx(_components.p, {
      children: "Our custom Details/Summary also works in CommonMark mode"
    }), "\n"]
  });
}

which is not the case for the mdx mode:

function _createMdxContent(props) {
  const _components = Object.assign({
    p: "p"
  }, props.components);
  return _jsxs("details", {
    children: [_jsx("summary", {
      children: "MD Summary"
    }), _jsx(_components.p, {
      children: "Our custom Details/Summary also works in CommonMark mode"
    })]
  });
}

I was able to make the details work in CommonMark by simply adding a lowercase details entry in the MDXProvider

slorber avatar Jun 22 '23 15:06 slorber

Some elements like SEO <head> also seem quite critical to fix.

Unless we are able to fix all these critical elements fast, I think we can consider our CommonMark mode as "experimental" and eventually stabilize it in a further minor release. For v3 I think it's safer to keep the MDX parser by default even for .md files. Considering the CommonMark mode is new, that shouldn't be a problem for the community to adopt this mode incrementally.

slorber avatar Jun 22 '23 15:06 slorber

In my case, I make a remark plugin to using directive :docusaurus-doc-card-list to make <DocCardList /> work in docusaurus v3 CommonMark mode.

Maybe all the features can be landing as directive.

Airkro avatar Nov 17 '23 03:11 Airkro

Hi @slorber,

It seems to me that diff and bash code blocks are not properly highlighted with CommonMark. Is this something that you have observed as well ?

antoinetissier avatar Apr 11 '24 17:04 antoinetissier

@antoinetissier most likely unrelated (unless proven with a repro), it's v3 that requires to declare these languages.

https://docusaurus.io/docs/migration/v3#prism-react-renderer-v20

CleanShot 2024-04-11 at 19 49 41

slorber avatar Apr 11 '24 17:04 slorber

I had missed that, thank you !

antoinetissier avatar Apr 12 '24 08:04 antoinetissier