Replies: 7 comments 9 replies
-
I don't understand, isn't it possible already with mdx or markdoc? Or are you talking specifically about .md files? |
Beta Was this translation helpful? Give feedback.
-
I'll upvote this! It shouldn't be necessary to install mdx in order to achieve such simple mappings a for common html tags to astro components. |
Beta Was this translation helpful? Give feedback.
-
related #423 |
Beta Was this translation helpful? Give feedback.
-
I tested how overrides work in MDX. Some of components work as expected, like |
Beta Was this translation helpful? Give feedback.
-
Extended proposal and some thoughts about API design IntroductionIdea is very similar to Hugo render hooks. Add ability to custmoize how markdown is rendered with Astro components: ---
// ...
const { Content } = await post.render();
---
<Content
components={{
h1: Heading1,
a: Link,
}}
/> Motivating examplesReuse componentsIf one already has Astro component it would be trivial to reuse it in markdown. For example, Starlight provides Instead one could do: // ContainerDirective.astro
---
import Aside from "./Aside.astro";
---
<Aside type={Astro.props.directive}>
<slot />
</Aside> and then <Content
components={{
containerdirective: ContainerDirective,
}}
/> Astro components are easier to deal with than remark/rehype pluginsRemark and rehype provide low level API, which is nice if you develop plugins, but for the end-users this causes a lot of confusion. Situation is very similar to Vite API. It is overkill for Astro integration layer. That is why there is Astro Integration Kit, which creates additional layer tailored speciafically for Astro use case. Take a look how much struggle it is to integrate Mermaid in Astro/Starlight. On the other hand with proposed API it would be a trivial task: // CodeOverride.astro
---
import { Code } from "astro:components";
import Mermaid from "./Mermaid.astro";
const { content, lang, inline } = Astro.props;
---
{
lang === "mermaid" ? (
<Mermaid diagram={content} />
) : (
<Code code={content} lang={lang} inline={inline} />
)
} and then <Content
components={{
code: CodeOverride,
}}
/> Astro components can be client-side componentsThis API opens up door to for using client-side components for Markdown, which would be hard to do with remark/rehype plugins. For example, one can override code-fences to render Google Maps in place. ```map
38.7223° N, 9.1393° W
``` With something like this: // CodeOverride.astro
---
import { Code } from "astro:components";
import GoogleMaps from "./GoogleMaps.astro";
const { content, lang, inline } = Astro.props;
---
{
lang === "map" ? (
<GoogleMaps center={content} />
) : (
<Code code={content} lang={lang} inline={inline} />
)
} Or if you have remark-directive, you can use special directive for this, for example: ::map[38.7223° N, 9.1393° W] The devil is in the detailsWhile all of this sounds nice, it may be not very clear how to design API. At which level shall it operate -
|
Beta Was this translation helpful? Give feedback.
-
If you need to pass components to the markdown, then MDX is the perfect solution for this. If we want to support passing components markdown without MDX, we have to rewrite the markdown rendering to render the HTML tag by tag, so that we know when to render a specific tag with a specific component. And if we did so, we're basically replicating what MDX does under the hood. So with that, it's better to use MDX as it's the right tool for the job. I don't think it makes sense to extend markdown rendering any further since it'll impact existing users who only need HTML and they'd have to pay the cost of the performance overhead of this feature. |
Beta Was this translation helpful? Give feedback.
-
I like this idea |
Beta Was this translation helpful? Give feedback.
-
Body
Summary
A better usage and handling of components and other instances around the
<Content />
component, allowing to override generated HTML from a markdown text.Background & Motivation
The principle around this RFC is to give a better DX around parsed markdown in Astro content. Allowing developers to reuse their external components inside rendered HTML from markdown file. Instead of doing it around
remark
andrehype
plugins and handling AST nodes directly, would be cool to have it being handled in theContent
instance.It would allow developers to reuse any component from Astro or any other framework allowed by Astro, like React, Vue, Svelte, etc. And by instance, so we would let to componentize the
<Content />
too.Goals
astro:content
Content component DX (Developer Experience);<Content />
component around their codebase;Example
Beta Was this translation helpful? Give feedback.
All reactions