Skip to content

stereobooster/astro-customize-markdown

Repository files navigation

Testing override for MDX with components

Testing how different overrides work in Astro:

  • Code - doesn't work as expected
    • inline not passed - no way to distinguish inline-code and block-code
      • had to do hack with props.class === undefined
    • lang not passed
      • had to do hack with class?.replace("language-", "")
    • block-code get's wrapped in extra pre
      • had to do hack with overriding pre and render it witout tag
    • <slot /> - content is HTML string, which means that one needs to unescape it
      • is there a way to use something like allowDangerousHTML to pass raw strings to some nodes?
    • metastring
  • remark-directive
    • works if you add smallRemarkAdapter, then leafdirective, containerdirective and textdirective can be handled with MDX overrides
  • Image - works as expected
    • src
    • alt
    • title
  • Link - works as expected
    • href
    • title
    • <slot />
  • Blockquote
    • <slot />
      • content is HTML string though
  • Heading
    • id
    • <slot />
    • {#custom-id} (works with remark plugin)
      • remark-custom-heading-id didn't work in my case
      • remark-heading-id works, but in MDX one needs to escape curly-braces \{#custom-id\}
      • see withastro/roadmap#329

Inspiration

Currently overrides only supported for MDX, but not for markdown. There is a proposal to support component overrides for markdown as well.

Ideally it should be as easy as Hugo render hooks.

Why does it matter?

Case study 1: Aside in Starlight

Starlight provides <Aside /> component.

Also it provides markdown support for it:

:::note
Highlights information that users should take into account, even when skimming.
:::

They basically duplicate code: once it is written as remark plugin and once it is written as Astro component.

Instead they can reuse it like this:

<Aside type={directive}>
  <slot />
</Aside>

Case study 2: Code in Starlight

Astro provides <Code /> component.

Also it provides markdown support for it:

```ts
const x = 1;
```

They basically duplicate code: once it is written as remark plugin and once it is written as Astro component.

Plus: if you want to customize it, for example, to add Mermaid support you need to jump through hoops to undo what built-in syntax highlighter does.

Instead they can reuse components like this:

{
  lang === "mermaid" ? (
    <Mermaid diagram={code} />
  ) : (
    <Code code={code} lang={lang} inline={inline} />
  )
}

Other potential use cases:

Case study 3: Heading

You may want to add anchors to headings. There is already rehype plugin for this - rehype-autolink-headings. But this requires quite some configuration in different places.

On the other hand overriding component encapsulates all logic in one place.

Case study 4: Link

You may want to add icons to external links or target="_blank" or rel="nofollow". There is already rehype plugin for this - rehype-external-links. But this requires quite some configuration in different places.

On the other hand overriding component encapsulates all logic in one place.

Case study 5: remark-directive

remark-directive allows to create shortcuts for components, for example, one can create:

  • :youtube{#TtRtkTzHVBU} to use astro-embed YouTube component. See TextDirective
  • :icon{mdi:account} to use astro-icon Icon component
  • :::tip to use Aside component (see above). See ContainerDirective

Ideas

One can implement remark/rehype plugin and use await astro.renderToString(Component, { props, slots, request, params }) to render components.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published