astro-community / md

Render any Markdown content in Astro, optionally integrating with any existing configuration.
https://stackblitz.com/github/astro-community/md
72 stars 7 forks source link

Option to render <a> anchor tags with target="_blank" and rel="noreferrer"? #20

Open JoshuaKGoldberg opened 3 months ago

JoshuaKGoldberg commented 3 months ago

I'd like to use this library to render some markdown that might have links to external pages. For those packages, it'd be good to render anchors with target="_blank" rel="noreferrer". But I can't figure out how to inject thatm.

The options: any from this package seem to point to https://docs.astro.build/en/reference/configuration-reference/#markdown-options... is that right?

Is there a sanctioned path with @astropub/md to add attributes to specific tags? If not, could we make one?

connor-baer commented 3 months ago

Since this package integrates with Astro's default Markdown configuration, you can use rehype and remark plugins to add the desired attributes. rehype-external-links should work well for your use case.

// astro.config.js
import { defineConfig } from 'astro/config'
import markdownIntegration from '@astropub/md'
import externalLinks from 'rehype-external-links'

export default defineConfig({
  integrations: [
    markdownIntegration(),
  ],
  markdown: {
    rehypePlugins: [
      [externalLinks, { rel: ['noreferrer'], target: '_blank' }]
    ],
  }
})
JoshuaKGoldberg commented 3 months ago

That works site-wide, I don't think that's quite what I'm looking for. Setting the behavior for all links might not be desirable. Is there a way to set specific settings in one <Markdown.Inline ... /> component / markdown.inline( ... ) function call?

connor-baer commented 3 months ago

Hm, looking at the source code, this would require creating a fresh markdown processor for each invocation of the markdown function to be able to pass it a custom markdown config. That has performance implications (see https://github.com/astro-community/md/issues/16), though that could be mitigated by only creating a custom processor when custom options are passed and reusing the global processor otherwise.

(I'm not a maintainer of this package, only a user, so please take this with a grain of salt)