Closed karlhorky closed 4 months ago
Heyyyyy!
This is intentional, because it isn’t needed, you can do:
Video: () => <div>video replacement</div>
And then:
<Video />
Why is this one character change, which is inspired by how JSX itself works (if you write <video>
it’s plain, if you write <Video>
it’s a reference), not viable for you?
Video
insteadThe following keys can be passed in components:
HTML equivalents for the things you write with markdown such as h1 for
# heading
(see § Table of > components for examples) wrapper, which defines the layout (but a local layout takes precedence)
- anything else that is a valid JavaScript identifier (foo, Quote, _, $x, a1) for the things you write with JSX (like
<So />
or<like.so />
, note that locally defined components take precedence
components
prop), both can change the HTMLis it preferred to use the word "replaces" or "overrides" like the community has been using? or something more like "renders" with a longer description?
it depends; importantly, MDX is not coupled to React. JSX runtimes could accept whatever. Functions, classes, symbols, whatever. It’s also not coupled to HTML semantics. You could do emails or rss feeds or ANSI rendering; so, whether you’re replacing/overriding/rendering/swapping/etc seems related to what else you’re doing
what is the preferred terminology for describing the plural things that are being passed as the keys of the object passed to the components prop?
names, keys, identifiers, fields? Keep in mind that JSX allows objects too; <very.deeply.nested />
, so very
here is also a key in components
I haven't yet collected all of the reasons why others have said they wanted this, but I'll list some reasons why overriding <video>
or other HTML literal tags may be desirable off the top of my head:
I can understand if there are technical reasons why MDX does not want to support these use cases - are there technical reasons for this? The original workaround suggested a plugin that no longer works. So if there's a technical reason for it not working or a new version of the workaround for changes in MDX, that would be interesting.
Regardless of whether there is a new workaround or not, I do think the whole flow should be more explicitly documented, with a few examples of what HTML tags are not replaced.
Here is a detailed list of suggestions, based on my original list above and your questions above, but reordered to match the order of the page:
4) A text description of what MDX does with "an object mapping component names to components", using preferred terminology
-There is one special prop: `components`. It takes an object mapping component names to components. Take this example:
+There is one special prop: `components`. Pass an object containing either / both of:
+
+1. Component name keys to components values eg. `Video: () => { ... }`
+2. HTML element names to components eg. `img: Image`
+
+MDX will use this object to replace any occurrences in your MDX file with the component passed as the value.
+
+Take this example:
This may have issues which require further clarification eg. that these key/value pairs above only apply to MDX with HTML.
example.mdx
and example.jsx
3) A short code example showing what the
components
prop does (not onlyexample.mdx
andexample.jsx
, but also the resulting HTML)
Take this example:
```mdx path="example.mdx"
# Hello *<Planet />*
It can be imported from JavaScript and passed components like so:
// @filename: types.d.ts
import type {} from 'mdx'
// @filename: example.jsx
/// <reference lib="dom" />
/* @jsxImportSource react */
// ---cut---
import Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.
console.log(
<Example
components={{
Planet() {
return <span style={{color: 'tomato'}}>Pluto</span>
}
}}
/>
)
+This results in the following HTML:
+
+html +<h1>Hello <span style="color: tomato">Pluto</span></h1> +
Again, my example above may likely be missing something or needs tweaks to be 100% accurate for the wide use cases of MDX - it's intended as an illustration of what I mean, and something that would be a very helpful missing piece to showcase what `components` does.
## 2) [Using MDX -> Components section](https://mdxjs.com/docs/using-mdx/#components) - Explicit description that HTML literal elements not replaced
> 2) An explicit description of this intended behavior - that MDX will by default not override or replace any HTML literal elements (maybe with a link to [the original issue](https://github.com/mdx-js/mdx/issues/821) as background?)
![Screenshot 2024-07-07 at 19 01 00](https://github.com/mdx-js/mdx/assets/1935696/d86840e4-f7fd-4114-a728-678ada62585f)
```diff
-The following keys can be passed in `components`:
+The following keys can be passed in a `components` object:
-* HTML equivalents for the things you write with markdown such as `h1` for
- `# heading` (see [§ Table of components][toc] for examples)
+* Markdown syntax-generated HTML elements eg. if you write `# heading` in your MDX file,
+ the key is `h1` (this does not include all HTML, see [§ Table of components][toc] for examples)
* `wrapper`, which defines the layout (but a local layout takes precedence)
-* `*` anything else that is a valid JavaScript identifier (`foo`,
+* anything else that is a valid JavaScript identifier (`foo`,
`Quote`, `_`, `$x`, `a1`) for the things you write with JSX (like
`<So />` or `<like.so />`, note that locally defined components take
precedence)**‡**
+
+Caveat: the following keys in a `component` object will not be replaced:
+
+* HTML elements which do not use Markdown syntax eg. `<img>`, `<video>`, etc. in `.mdx` files
+ ([see background](https://github.com/mdx-js/mdx/issues/821)) - for these use cases, use a custom component like `Video: () => { ... }`
**‡** If you ever wondered what the rules are for whether a name in JSX (so `x`
in `<x>`) is a literal tag name (like `h1`) or not (like `Component`), they are
as follows:
A few first suggestions above.
Considering it more, I think that the potential confusion of HTML literal elements not being replaced would actually warrant another section showing:
.mdx
file.jsx
file (with components
prop, some of which are invalid eg. video
)To be a companion for the text to be 100% explicit that some components (such as literal HTML elements in the .mdx
file) will not be replaced, and will have the original elements as in the .mdx
file.
- Why are the existing docs not clear? Emphasis to show what I mean
As in my diff above:
HTML
, which is misleading and makes the rest of the words in that first bullet aim to try to explain that they are related to Markdown syntaxcomponents
object keys<video>
*
in the last bullet looks like a literal value that can be used (eg. like the *
selector in CSS). I'm assuming that this is not the case, so I reworded for clarity
- Isn’t that the example at “Here are some other examples of passing components”? It has text explaining each thing in the comments?
I think your comment was mostly referring to my 2) suggestion. It doesn't relate to 3) because 3 is about having an HTML result example directly next to the other example.mdx
and example.jsx
code blocks.
Including the screenshot of the example code block here for reference:
I like this example code block, yes! I don't think that it describes in detail which things can and cannot be used (which I'm proposing in 2), and the comments are pretty easy to miss. But I love these types of examples, and I think it's very valuable.
example.mdx
and example.jsx
3i) A short code example showing that the resulting HTML does not change with usage of the MDX provider
Same idea as above with 3) - a separate HTML "result" code block. Showing that the resulting HTML is the same, to make the mental models concrete that the docs reader is building up and confirm their assumptions.
Thanks for sharing @karlhorky!
This comes up often enough I'd be okay with there being some documentation. Similar to @wooorm I view overriding plain HTML as a really bad idea. So if it were included it may make sense to do something like Micromark extensions https://github.com/micromark/micromark?tab=readme-ov-file#extending-markdown
With a sizable section on alternatives and why you may not want to do this (most people), before offering a path to the persistent who have a super specific use case.
I haven't yet collected all of the reasons why others have said they wanted this, but I'll list some reasons why overriding
<video>
or other HTML literal tags may be desirable off the top of my head:
The only people I am aware of that brought this up was people migrating.
- copying and pasting HTML
This is not a goal, as copy/pasting HTML into MDX will not work. Think about className
. Or self-closing/void.
Then, copy/pasting HTMLJSX is the main reason why this is the way it is.
Humans want their MyLink
for []()
. Then they copy/paste some JSX in. They don’t expect that <a>
they copy/pasted to turn into MyLink
.
You are arguing about <video>
here, an element that doesn’t naturally occur in markdown.
But the change you argue for applies to the things that do occur in markdown. Say, <p>
, <h1>
, <code>
, <em>
, <blockquote>
, etc.
Where it is common for people to overwrite their markdown counterparts. But also include the “vanilla” elements in some more complex embedded JSX.
- tooling integrations for HTML elements eg. linting for attributes which should be there
- greppability in codebase
I argue this the other way around: if you are going to use a <MyVideo>
component, you are likely using different props than an HTML <video>
. You gain a lot by using MyVideo
/ YouTube
. You can be much stricter. Accept fewer props. Ignore the obsolete archaic things that HTML has to support. For YouTube
, you can accept an ID.
A linter will think that video
is a video
and not a Video
.
Grepping for video
or Video
is the same.
- style preference towards usage of HTML elements instead of Markdown elements / JSX elements
Perhaps I am not 100% on what you mean, but I think this preference is wrong, it doesn’t work due to className
and self-closing/void anyway? If you want HTML, you don’t need the MDX language. Markdown can have HTML in it. @mdx-js/mdx
can support .md
files with HTML.
with a few examples of what HTML tags are not replaced.
Which tags are (not) replaced?
+There is one special prop: `components`. Pass an object containing either / both of: + +1. Component name keys to components values eg. `Video: () => { ... }` +2. HTML element names to components eg. `img: Image` + +MDX will use this object to replace any occurrences in your MDX file with the component passed as the > value. + +Take this example:
I think this is getting very close to what is at the end of that section already:
The following keys can be passed in `components`: * HTML equivalents for the things you write with markdown such as `h1` for `# heading` (see [§ Table of components][toc] for examples) * `wrapper`, which defines the layout (but a local layout takes precedence) * `*` anything else that is a valid JavaScript identifier (`foo`, `Quote`, `_`, `$x`, `a1`) for the things you write with JSX (like `<So />` or `<like.so />`, note that locally defined components take precedence)**‡** **‡** If you ever wondered what the rules are for whether a name in JSX (so `x` in `<x>`) is a literal tag name (like `h1`) or not (like `Component`), they are as follows: * If there’s a dot, it’s a member expression (`<a.b>` -> `h(a.b)`), which means that the `b` component is taken from object `a` * Otherwise, if the name is not a valid identifier, it’s a literal (`<a-b>` -> `h('a-b')`) * Otherwise, if it starts with a lowercase, it’s a literal (`<a>` -> `h('a')`) * Otherwise, it’s an identifier (`<A>` -> `h(A)`), which means a component `A`
+This results in the following HTML: + +```html +<h1>Hello <span style="color: tomato">Pluto</span></h1> +```
The examples in these docs don’t focus on input -> output, for several reasons. It becomes very verbose when you explain everything with a complete working playground. Those have benefits of course. But there are places for more succinct documentation to explain concepts with pseudo-code. I wonder what including this output would add for you. What else could come out?
-The following keys can be passed in `components`: +The following keys can be passed in a `components` object:
For me “keys in x” already implies object, I don’t think this change is needed?
-* HTML equivalents for the things you write with markdown such as `h1` for - `# heading` […] +* Markdown syntax-generated HTML elements eg. if you write `# heading` in your MDX file, + the key is `h1` […]
I don’t think your change is an improvement. What do you attempt to say? (note: i also respond to this in a bullet below)
- (see [§ Table of components][toc] for examples) + (this does not include all HTML, see [§ Table of components][toc] for examples)
I don’t think the change is correct. There is a previous sentence: it does include all HTML equivalents for the things you write with markdown.
+Caveat: the following keys in a `component` object will not be replaced: + +* HTML elements which do not use Markdown syntax eg. `<img>`, `<video>`, etc. in `.mdx` files + ([see background](https://github.com/mdx-js/mdx/issues/821)) - for these use cases, use a custom > component like `Video: () => { ... }`
Well, a) I really don’t consider this a “caveat”, and, b) I believe this duplicating what comes after:
**‡** If you ever wondered what the rules are for whether a name in JSX (so `x` in `<x>`) is a literal tag name (like `h1`) or not (like `Component`), they are as follows: * If there’s a dot, it’s a member expression (`<a.b>` -> `h(a.b)`), which means that the `b` component is taken from object `a` * Otherwise, if the name is not a valid identifier, it’s a literal (`<a-b>` -> `h('a-b')`) * Otherwise, if it starts with a lowercase, it’s a literal (`<a>` -> `h('a')`) * Otherwise, it’s an identifier (`<A>` -> `h(A)`), which means a component `A`
This “caveat” is a fundament of JSX: how to differentiate between a reference to a variable and a literal tag name.
Perhaps we can illustrate that section by following it with an example of this sort:
A markdown [link](https://alpha.com),
a regular lowercase JSX element <a href="https://bravo.com">link</a>, and
a JSX component <MyLink href="https://charlie.com">link</MyLink>.
…and then with:
a(props) { return <a {...props} style={{color: 'red'}} /> },
MyLink(props) { return <a {...props} style={{color: 'blue'}} /> }
…and then show the generated HTML? Perhaps even rendered (red, mdx link color, blue)?
some of which are invalid eg. video
It’s not that video
is “invalid”. MDX works with plugins. Plugins could make that video “valid”. It’s more that, as described above, whether a
does something, depends on things.
- the first bullet point starts with HTML, which is misleading and makes the rest of the words in that first bullet aim to try to explain that they are related to Markdown syntax
I dunno, the second word is “equivalent”. And then there’s a whole sentence. The first words of each bullet here relate to the “key” concept in the introductory sentence. Changing this one breaks that sentence, and then this list. The first thing is an HTML tag name. Rest of the sentence explains which ones.
- there is no mention of any exceptions to HTML, except for the link that goes to a different page
That’s because <a>
/<video>
are not covered by this bullet. They are covered by the last bullet point. Which has a footnote.
- there is no mention of what users cannot use in the components object keys
No “disallowlist” is needed because there’s only “allowlist”s. There are cases where <video>
or <x>
can be used. The first point references valid HTML tag names, second id just wrapper
, last catchall last references valid JavaScript identifier.
- there is no suggestion of what users do if they run into the limitation of
<video>
I described this in more depth already but in short: how to use references in JSX (MyVideo
) is explained in the ‡
rules.
unrelated to the HTML elements point: the
*
in the last bullet looks like a literal value that can be used (eg. like the * selector in CSS). I'm assuming that this is not the case, so I reworded for clarity
Ok, I think this one is fine.
3i) A short code example showing that the resulting HTML does not change with usage of the MDX provider
Same idea as above with 3) - a separate HTML "result" code block. Showing that the resulting HTML is the same, to make the mental models concrete that the docs reader is building up and confirm their assumptions.
Same as the above. I don’t think output is needed; This section isn’t about the input, or the components, or the output. It’s about whether components
work. How to use <Readme />
. Not what’s inside it. Or what it results in.
We don't need to go over the reasons for why to use <video>
- I don't have strong feelings or opinions here yet because I haven't heavily used this.
I have a gut feeling that the rebuttals of my reasons are not necessarily taking in the complete picture, but then again, it's possible that you just have more experience than me with these things and have already gone down these roads far enough to see more.
Given more usage of <video>
or other HTML tags, I may have other reasons or feel more strongly about the reasons I wrote and be able to argue for them better.
with a few examples of what HTML tags are not replaced.
Which tags are (not) replaced?
I wonder what including this output would add for you. What else could come out?
For me “keys in x” already implies object, I don’t think this change is needed?
I think this is getting very close to what is at the end of that section already:
- there is no mention of what users cannot use in the components object keys
No “disallowlist” is needed because there’s only “allowlist”s. There are cases where
<video>
or<x>
can be used. The first point references valid HTML tag names, second id justwrapper
, last catchall last references valid JavaScript identifier.
I think it's all the same answer for these: the examples and additional explicitness are meant to be aids to help make the concepts concrete for learners.
My reasoning is in my experience of seeing that explaining one thing one way, in terse writing and only partially (even if it can be explained eg. in this issue as being a full explanation) will lead to misunderstandings and half-formed knowledge.
To the "partially" point:
- the first bullet point starts with HTML, which is misleading and makes the rest of the words in that first bullet aim to try to explain that they are related to Markdown syntax
I dunno, the second word is “equivalent”. And then there’s a whole sentence. The first words of each bullet here relate to the “key” concept in the introductory sentence. Changing this one breaks that sentence, and then this list. The first thing is an HTML tag name. Rest of the sentence explains which ones.
- there is no mention of any exceptions to HTML, except for the link that goes to a different page
That’s because
<a>
/<video>
are not covered by this bullet. They are covered by the last bullet point. Which has a footnote.
Some sections and bullets feel like they have high potential for misunderstanding, including the bullet about HTML-equivalent elements. Restructuring the bullet text to start with a different word than "HTML" and adding a caveat are 2 ways to be explicit to avoid misunderstandings.
This “caveat” is a fundament of JSX: how to differentiate between a reference to a variable and a literal tag name.
Perhaps we can illustrate that section by following it with an example of this sort:
A markdown [link](https://alpha.com), a regular lowercase JSX element <a href="https://bravo.com">link</a>, and a JSX component <MyLink href="https://charlie.com">link</MyLink>.
…and then with:
a(props) { return <a {...props} style={{color: 'red'}} /> }, MyLink(props) { return <a {...props} style={{color: 'blue'}} /> }
…and then show the generated HTML? Perhaps even rendered (red, mdx link color, blue)?
An example would definitely help and at least partly achieve many of the things I'm aiming to with these suggestions 👍
It becomes very verbose when you explain everything with a complete working playground.
I don't mean to suggest a full playground here - I'm suggesting showing the output, which is the step in between which these examples are missing.
- there is no suggestion of what users do if they run into the limitation of
<video>
I described this in more depth already but in short: how to use references in JSX (
MyVideo
) is explained in the‡
rules.
I don't think there's a suggestion anywhere that <Video>
should be used instead of <video>
(or any other example of HTML tags like this).
Having an explicit, blessed suggestion for using <Video>
instead of <video>
or <Img>
instead of <img>
(and why) would avoid users reading through issues or asking.
But maybe this actually is even bigger than I'm thinking and needs its own section, with use cases:
<video>
and not having custom functionality)This actually is kind of similar to what is above in your suggestion in "Alternative "caveat" suggestion", wonder if these could be combined... 🤔
We don't need to go over the reasons for why to use
I have a gut feeling that the rebuttals of my reasons are not necessarily taking in the complete picture, but then again, it's possible that you just have more experience than me with these things and have already gone down these roads far enough to see more.
Given more usage of
I don't think there's a suggestion anywhere that
I think it's all the same answer for these: the examples and additional explicitness are meant to be aids to help make the concepts concrete for learners.
There is hierarchy to this solution space
There are a lot of ways to solve an issue like this.
Plain <video>
is fine, and can be used with fully qualified urls/domains and absolute paths, which work regardless of where they on your site.
💡 use the platform first
If you want more features/customizations in how a video is rendered.
Components are supported like <Video>
💡 if you don't use the platform, use the framework
If for some reason you choose not to use the platform or the framework, then yes, using MDX advanced internals you can change how the content works. This is not a beginner topic, generally not a good idea, and should not be labelled as a recommended beginner approach.
You very well may have a valid use case for it, I appreciate and respect that. That does not mean everyone should do the same thing.
style preference towards usage of HTML elements instead of Markdown elements / JSX elements
Then use HTML, don't turn standard HTML elements into something custom. That is what HTML custom elements and React Components are for.
But maybe this actually is even bigger than I'm thinking and needs its own section, with use cases:
- When should I use Markdown syntax? examples/upsides/downsides (downsides include not being able to express things like
and not having custom functionality) - When should I use HTML syntax? examples/upsides/downsides (downsides include remark/rehype plugins accessing the element and not having custom functionality)
- When should I use component syntax? examples/upsides/downsides (downsides include remark/rehype plugins not acting on these elements)
This feels more appropriate
Removed the asterisk in 90f509bd.
An example would definitely help and at least partly achieve many of the things I'm aiming to with these suggestions 👍
Done in 044e8b2a.
Further responses to most of your comments.
I don't have strong feelings or opinions here yet because I haven't heavily used this.
I have a gut feeling that the rebuttals of my reasons are not necessarily taking in the complete picture
This sounds contradictory. You haven’t used this much but we are the ones missing the complete picture. 😅 I do have experience using it; listening to different humans; coming up with arguments; changing it; defending it. It could definitely be that I don’t know your complete picture yet, feel free to explain it more in-depth. I believe that when you use JSX more, you will feel similar.
the examples and additional explicitness are meant to be aids to help make the concepts concrete for learners.
I think there’s also a trade off here. My argument goes similar to how I argued for science papers somewhere else: one does not get far if one constantly has to explain every concept in detail, so that it can be understood by beginners, that don’t read the surrounding text. More text costs every reader too. There is an alternative: different docs explainings different things. Docs building on each other. Different styles of articles (i.e., the docs vs the guides). A good playground where people can play and see.
My reasoning is in my experience of seeing that explaining one thing one way, in terse writing and only partially (even if it can be explained eg. in this issue as being a full explanation) will lead to misunderstandings and half-formed knowledge.
To the "partially" point:
I don't think the examples offer a full explanation without the result teaching this more completely would be both an "allowlist" and some examples in a "disallowlist"
These are broad statements. There are of course cases where they can be implemented. But there might be cases where I don‘t think it’s needed. I’d appreciate it when they can be made concrete: which concepts are explained a singular way? I may be able to point to other docs that explain it other ways. Or more completely.
Particularly regarding the “will lead to misunderstandings and half-formed knowledge” part: I believe this to be inevitable for learners. Not even for just for the beginners, that grow (and can only grow due to it). But anyone reading a sentence once will have misunderstandings and half-formed knowledge. Anyone only reading theory and not putting it into praxis will misunderstand.
Restructuring the bullet text to start with a different word than "HTML" and adding a caveat are 2 ways to be explicit to avoid misunderstandings.
I fail to see this. I don’t see a problem here nor an improvement in the suggestion: these values for keys do come from the HTML spec. Not RSS or SVG or JS or CSS. p
, strong
, h1
, td
are HTML equivalent to things in markdown. I don’t see how this concept can be explained differently.
Perhaps reading through the earlier document “What is MDX?” might be useful in clearing up what HTML syntax / JSX syntax mean, in relation to MDX?
I don't mean to suggest a full playground here - I'm suggesting showing the output, which is the step in between which these examples are missing.
The output is missing for all these examples, in this document and in “What is MDX?”, because it doesn’t matter what the output is here. So I am extrapolating what you are asking for: if here, why not everywhere? If output, why not a package.json, or entire playgrounds?
I don't think there's a suggestion anywhere that
<Video>
should be used instead of<video>
(or any other example of HTML tags like this).Having an explicit, blessed suggestion for using
<Video>
instead of<video>
or<Img>
instead of<img>
(and why) would avoid users reading through issues or asking.
It’s not there because I don‘t think that question is for that spot. There is an explanation of the difference between h1
and Component
. And now there’s an illustration of []()
vs a
vs Link
. But when to use <video>
, as christian mentions, has more to do with the web, choosing <Video>
has more to do with React. That <video>
and <Video>
are two things is about JSX.
I think this section is more about the difference. Not about tips on what one should choose in different circumstances.
But maybe this actually is even bigger than I'm thinking and needs its own section, with use cases:
When should I use Markdown syntax? […] / When should I use
HTML syntax? […] When should I use component syntaxJSX syntax? […]
Sure. How to use MDX at scale. How to enjoy writing MDX. MDX patterns. Stuff like that could all be its own guides. They are more tied to personal opinions. And presumably also more tied to a particular platform or a framework. So where it goes depends on what you want to suggest!
Coming back to the original issue, I think this can be closed.
video
and Video
in JSX (which is also described in What is MDX?); it is understandable of course that OP went down rabbit holes and found old issues, but both are alluded to/shown/explained in docs already, I wonder if mentioning it more often would’ve prevented going into old issuesthe root of the problem OP ran into, as discussed in the other discussion, has I believe more to do with Webpack/Next.js than with video
and Video
or with compilers and plugins. As the following worked:
import myVideoSource from './some-video.mp4'
<video src={myVideoSource} controls />
Do please comment when you want to add something important: comments still work on closed issues. But also consider my goal is to move to concrete improvements and discussions.
Ok, thanks! The commit 044e8b2a272186be04d16c270f5621718cc8a57e does achieve 2 things in my perspective:
<a>
I think what's missing is:
<a>
components
, but it doesn't tell us what it's doing with that until further down. it doesn't need to be long text)But maybe this actually is even bigger than I'm thinking and needs its own section, with use cases: When should I use Markdown syntax? […] / When should I use ~HTML syntax? […] When should I use component syntax~JSX syntax? […]
Sure. How to use MDX at scale. How to enjoy writing MDX. MDX patterns. Stuff like that could all be its own guides. They are more tied to personal opinions. And presumably also more tied to a particular platform or a framework. So where it goes depends on what you want to suggest! I'm suggesting something smaller than a guide - probably 3 short bullets similar to what Christian wrote showcasing the strengths and weaknesses of each, and highlighting that it is the suggestion of the MDX team to not use
<video>
or<img>
but rather<Video>
and<Img>
in circumstances where extension of the element is wanted (and what circumstances/benefits are better for Markdown syntax instead)
This comes up often enough I'd be okay with there being some documentation. Similar to @wooorm I view overriding plain HTML as a really bad idea. So if it were included it may make sense to do something like Micromark extensions micromark/micromark#extending-markdown
components
keys (HTML literal elements and those which cannot occur in Markdown)I opened a PR for 1 (I originally suggested HTML, but I kept JSX for the output), 2, 3 and 4 for first feedback:
Because the rest of the points seem lower likelihood to be accepted, I have held off with creating a PR for those.
Showing the output as code
There are a lot of different outputs. This may be a case for having embedded playgrounds elsewhere in the site. https://mdxjs.com/playground/
An explicit mention that MDX doesn't modify
<a>
I'm a bit cautious about starting a dumping ground of all the things MDX doesn't do. Which is infinite.
Visual formatting of the new points in the paragraph, to make it easier to scan, in a structure that visually mimics the code above
Improved formatting is welcome!
The MDX team suggestion for using custom components instead of HTML elements, including HTML elements non-expressible in Markdown
I'd second Titus' point here. Markdown is a language, people can use the parts of the syntax they want. There isn't necessarily a suggestion of "don't use HTML". It would be more valuable to articulate trade offs of Markdown, HTML, Custom Elements, and plugins/content level manipulation. So that adopters can make an informed decision.
Mention of some Micromark workaround for users who still have a use case for HTML element overrides
Not quite what I was getting across here. Micromark is even lower level than working on the syntax tree. I'm more getting at documenting how to do some different types of content manipulation with plugins. But tying into the point above, making users aware of the complexity and trade offs, so new users have an idea what they are getting into.
The "disallowlist" idea as a teaching tool, for breaking any misconceptions as to what cannot go in the components keys (HTML literal elements and those which cannot occur in Markdown)
It feels like this may be best at the type level first. Perhaps leveraging something like https://www.typescriptlang.org/play/?#code/PTAEFEDsGcFcCcCm1QBcAWjQDMCW9pVQBjdAQ3jONUXlFxVgAcnbizpEAoVAT1dABJaAFUWbDogA8AZVCIAHjUgATFIXi5IAcwB8oALyg5i5WtBjW8dp1n6A-GniwsALhxkANpwDcXLiAQMAjIaJigGlraEagUqCgA7rgYoGQkZEzJXqCeiKg08Dz8WDKx8PEA6snoAMIZWZ6y8kqIquqomjr6RiYtbaAABgAkAN5a2LSgAGIAvqPjkwBKMwNcoKCOwpYStlP6pq3mHS5r6xvGp+vukIgAbrSn13e0fgFgAGpeuCrNZAC2TFyRQEAHEkHkooZjGVKtU6plYo0AOQACUQnk8AHskbofKBAgAVYqgVHorFI-yBQSQW5fH6Kf6ArAACmg6ExsE8PwARlgkTd7vAkQBKYFYam0zzfMGICE6KGlOLQKoYeENKRIzAY7G4-FgIkCfnPIWU-XIVCQpIpKioWDZWmaMjc3LQLjETEwIiS6Xgi06dwyuXRIyk7VIvGE9AMegoPA3N0ewj0Gl0wN+7TuCWp32QkNa8kR-VR9Tszk-diwTipUAGxAyYiaJhEWjwTGFIA /cc @remcohaszing
- Showing the output as code
This is intentionally omitted. I mentioned in previous comments why I don’t believe the output is not relevant here. As Christian mentions, to MDX, there are also infinite outputs. And, it’s explained in a preview and prose already (next point). Christian mentions this too.
- An explicit mention that MDX doesn't modify
<a>
It is explicitly described in the paragraph after.
- Visual formatting of the new points in the paragraph, to make it easier to scan, in a structure that visually mimics the code above
Perhaps I don’t know what you mean. The following paragraph does describe visual formatting. Do you mean using those colors and borders in the text as well? That doesn’t feel good. When you highlight everything, nothing is highlighted.
- An explicit text description of what MDX does with "an object mapping component names to components", using preferred terminology
- (I still think there should be some short text in the first paragraph under "Components" - the current first paragraph "There is one special prop: components. It takes an object mapping component names to components. Take this example:" sounds to me like it's trying to avoid saying what it is for - MDX takes components, but it doesn't tell us what it's doing with that until further down. it doesn't need to be long text)
I don’t believe it’s needed here: I am sure you are aware of “show, don’t tell”; and repetition has also already been noted in the discussions too. Showing and then telling seems fine. I don’t see what tell then show then tell again adds.
- The MDX team suggestion for using custom components instead of HTML elements, including HTML elements non-expressible in Markdown. Ideally of course as a few bullets instead, which Titus replied to here: […]
- I'm suggesting something smaller than a guide - probably 3 short bullets similar to what Christian wrote showcasing the strengths and weaknesses of each, and highlighting that it is the suggestion of the MDX team to not use
<video>
or<img>
but rather<Video>
and<Img>
in circumstances where extension of the element is wanted (and what circumstances/benefits are better for Markdown syntax instead)
I don’t really see it. Strengths and weaknesses. Here. MDX supports markdown and JSX. What you subjectively think is a great idea in your current stack has little to do with MDX. Perhaps you are looking for “What is MDX”.
I am open, like Christian, to a guide or similar somewhere on when to choose Markdown/HTML/custom elements/plugins/transforms/syntax extension.
- Mention of some Micromark workaround for users who still have a use case for HTML element overrides
Christian’s answer is sufficient here I believe.
- The "disallowlist" idea as a teaching tool, for breaking any misconceptions as to what cannot go in the components keys (HTML literal elements and those which cannot occur in Markdown)
Anything is possible there.
I think you are looking for the table of components, which is already linked: https://mdxjs.com/table-of-components/. It doesn’t contain video
.
At the bottom of the table, it mentions that plugins could add support for anything (also video
).
With "visual formatting" I mean making the prose visually structured and designed like the code it's describing, making it easier to scan and match up with the code while looking back and forth between the code and prose. Since there are 3 JSX elements, I added 3 bullet points.
The idea behind it: the visual shape of the prose and code in writing and docs is important for scanning, making it inviting and not burying info (also which word starts a line or sentence).
I don’t believe it’s needed here: I am sure you are aware of “show, don’t tell”; and repetition has also already been noted in the discussions too. Showing and then telling seems fine. I don’t see what tell then show then tell again adds.
Right, I think this is where a key disagreement (which appears unresolvable) is - in my (strong) opinion coming from lots of observation, repetition is very useful for beginners, and has only the downside of taking up space, which I'm trying to minimize with keeping it short. Terseness and purity are good for the authors (less to produce) and maybe for making it more visually minimal, but the downsides are bigger - that it doesn't get the point across.
Probably my opinion and suggestions and style for teaching beginners is just incompatible with the MDX style, so I think me contributing less is the best choice here. It feels insurmountable to introduce change to the current MDX style. I'll still do small PRs as they come up but I'll keep in mind that the method of teaching is probably not going to change.
What you subjectively think is a great idea in your current stack has little to do with MDX
Interesting, what are the biggest, most popular uses and consumers of MDX? I thought for sure it would be the React ecosystem, haven't seen it in big projects elsewhere.
I don't really have a strong opinion on where it should go in the docs, but at the point that the concept of component replacement is being introduced (which is where I'm suggesting it go), I would expect a small overview of those "best practices" from the MDX team to be introduced (maybe linked to another short guide somewhere). As of now, these best practices are buried in issues. So even putting it somewhere non-ideal would be an improvement in visibility.
repetition is very useful for beginners
Sure. There is already repetition. By this logic 5 or 20 repetition is an improvement.
Interesting, what are the biggest, most popular uses and consumers of MDX? I thought for sure it would be the React ecosystem, haven't seen it in big projects elsewhere.
I don’t think that’s relevant. Not only the biggest mass of beginners deserves docs on this website. You are free to teach only React beginners. There are React-specific docs here. It’s also used in many examples. But it’s not the focus. By this logic we should drop React on this website for PHP or Rails.
Initial checklist
Affected packages and versions
@mdx-js/react@3.0.1, next@14.2.4, react@^18
Link to runnable example
No response
Steps to reproduce
app-dir-mdx
example from Remcoexperimental.mdxRs
fromnext.config.js
video: () => <div>video replacement</div>
inmdx-components.tsx
<video />
inapp/message.mdx
<video />
appearing in HTML in DevTools, instead of the<div>
rehypePlugin
suggested by @wooorm)<video />
still appearing in HTML in DevTools, instead of the<div>
Or, to skip steps 1-6, a reproduction repo:
This has occurred because some users have seen the "overriding literal HTML in MDX" as unexpected behavior (as in @adamwathan's original https://github.com/mdx-js/mdx/issues/821). Other users (including myself) have found it unexpected that these HTML elements are not being overridden, especially in the case of HTML elements which have no Markdown syntax equivalent, such as
<video>
, where it would be amazing to be able to userehype-mdx-import-media
with<video>
out of the box without any additional plugins:Expected behavior
The Using MDX page (specifically the Components section and the MDX provider section) should include:
components
prop does (not onlyexample.mdx
andexample.jsx
, but also the resulting HTML)components
prop?Actual behavior
The Using MDX page (specifically the Components section and the MDX provider section) includes:
<video>
, writing an additional remark plugin for support of![]()
syntax can work)example.mdx
andexample.jsx
, not including the resulting HTMLexample.mdx
andexample.jsx
resulting HTML does not change with usage of the MDX providerRuntime
Node v20
Package manager
No response
OS
macOS
Build and bundle tools
Next.js