-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add a Sätteri tab in the remark/rehype recipes #14277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ArmandPhilippot
wants to merge
14
commits into
main
Choose a base branch
from
armand/satteri-recipes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
449aee4
feat: add Sätteri tab in the external links recipe
ArmandPhilippot 67d1197
remove the unified note as this is a wrong statement
ArmandPhilippot 9d1e97a
small rewording around "remark plugin"
ArmandPhilippot 1941057
add a Sätteri tab to the modified time recipe
ArmandPhilippot bf63cfe
fix a few TS/formatting issues
ArmandPhilippot fd175cc
revert a few changes, no need for getStaticPaths type actually
ArmandPhilippot 6f581c2
fix highlighting
ArmandPhilippot 0b7a914
add a Sätteri tab to the reading time recipe
ArmandPhilippot 78c7307
inverse tabs and steps in `modified-time.mdx`
ArmandPhilippot 6c0ce24
inverse steps and tabs in `reading-time.mdx`
ArmandPhilippot c578b00
add a new MarkdownProcessorTabs to make sure the same key is used
ArmandPhilippot 5986fa0
reduce verbosity in `external-links` recipe
ArmandPhilippot ca27346
reword and improve code snippet readability
ArmandPhilippot 56b0b99
Merge branch 'main' into armand/satteri-recipes
ArmandPhilippot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| import { Tabs, TabItem } from '@astrojs/starlight/components'; | ||
| --- | ||
|
|
||
| <Tabs syncKey="markdown-processor"> | ||
| <TabItem label="Sätteri"> | ||
| <slot name="satteri" /> | ||
| </TabItem> | ||
| <TabItem label="Unified"> | ||
| <slot name="unified" /> | ||
| </TabItem> | ||
| </Tabs> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,68 +1,137 @@ | ||
| --- | ||
| title: Add icons to external links | ||
| description: Learn how to install a rehype plugin to add icons to external links in your Markdown files. | ||
| description: Learn how to use a Markdown plugin to add icons to external links in your Markdown files. | ||
| i18nReady: true | ||
| type: recipe | ||
| --- | ||
| import { Steps } from '@astrojs/starlight/components'; | ||
| import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; | ||
| import MarkdownProcessorTabs from '~/components/tabs/MarkdownProcessorTabs.astro'; | ||
|
|
||
| Using a rehype plugin, you can identify and modify links in your Markdown files that point to external sites. This example adds icons to the end of each external link, so that visitors will know they are leaving your site. | ||
| Using a Markdown plugin, you can identify and modify links in your Markdown files that point to external sites. This example adds an icon to the end of each external link, so that visitors will know they are leaving your site. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - An Astro project using Markdown for content pages. | ||
|
|
||
| ## Recipe | ||
|
|
||
| <Steps> | ||
| 1. Install both the [`rehype-external-links`](https://www.npmjs.com/package/rehype-external-links) plugin and [`@astrojs/markdown-remark`](https://www.npmjs.com/package/@astrojs/markdown-remark). | ||
| <MarkdownProcessorTabs> | ||
| <Fragment slot="satteri"> | ||
| <Steps> | ||
| 1. Install both [`@astrojs/markdown-satteri`](https://www.npmjs.com/package/@astrojs/markdown-satteri) and [`satteri`](https://www.npmjs.com/package/satteri): | ||
|
|
||
| <PackageManagerTabs> | ||
| <Fragment slot="npm"> | ||
| ```shell | ||
| npm install rehype-external-links @astrojs/markdown-remark | ||
| <PackageManagerTabs> | ||
| <Fragment slot="npm"> | ||
| ```shell | ||
| npm install @astrojs/markdown-satteri satteri | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="pnpm"> | ||
| ```shell | ||
| pnpm add @astrojs/markdown-satteri satteri | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="yarn"> | ||
| ```shell | ||
| yarn add @astrojs/markdown-satteri satteri | ||
| ``` | ||
| </Fragment> | ||
| </PackageManagerTabs> | ||
|
|
||
| 2. Create a [Sätteri `hast` plugin](https://satteri.bruits.org/docs/plugins/#hast-plugins) that adds an icon if the link starts with `http`: | ||
|
|
||
| ```ts title="src/hast/hast-external-links.ts" | ||
| import { defineHastPlugin } from 'satteri'; | ||
|
|
||
| export const hastExternalLinks = defineHastPlugin({ | ||
| name: "hast-external-links", | ||
| element: { | ||
| filter: ["a"], | ||
| visit(node, context) { | ||
| if (node.properties.href?.startsWith("http")) { | ||
| context.appendChild(node, { | ||
| type: "element", | ||
| tagName: "span", | ||
| properties: { ariaHidden: "true" }, | ||
| children: [ | ||
| { | ||
| type: "text", | ||
| value: "🔗", | ||
| }, | ||
| ], | ||
| }); | ||
| } | ||
| }, | ||
| }, | ||
| }); | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="pnpm"> | ||
| ```shell | ||
| pnpm add rehype-external-links @astrojs/markdown-remark | ||
|
|
||
| 3. Configure the plugin in your `astro.config.mjs` file. | ||
|
|
||
| Import `satteri()` from `@astrojs/markdown-satteri` and define it as the Markdown processor to [define custom Sätteri plugins](/en/guides/markdown-content/#using-sätteri-plugins-and-features). Then, pass to `hastPlugins` an array containing your imported `hastExternalLinks` plugin. | ||
|
|
||
| ```js title="astro.config.mjs" | ||
| import { satteri } from '@astrojs/markdown-satteri'; | ||
| import { defineConfig } from 'astro/config'; | ||
| import { hastExternalLinks } from './src/hast/hast-external-links'; | ||
|
|
||
| export default defineConfig({ | ||
| markdown: { | ||
| processor: satteri({ | ||
| hastPlugins: [hastExternalLinks], | ||
| }), | ||
| }, | ||
| }); | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="yarn"> | ||
| ```shell | ||
| yarn add rehype-external-links @astrojs/markdown-remark | ||
| </Steps> | ||
| </Fragment> | ||
| <Fragment slot="unified"> | ||
| <Steps> | ||
| 1. Install both the [`rehype-external-links`](https://www.npmjs.com/package/rehype-external-links) plugin and [`@astrojs/markdown-remark`](https://www.npmjs.com/package/@astrojs/markdown-remark). | ||
|
|
||
| <PackageManagerTabs> | ||
| <Fragment slot="npm"> | ||
| ```shell | ||
| npm install rehype-external-links @astrojs/markdown-remark | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="pnpm"> | ||
| ```shell | ||
| pnpm add rehype-external-links @astrojs/markdown-remark | ||
| ``` | ||
| </Fragment> | ||
| <Fragment slot="yarn"> | ||
| ```shell | ||
| yarn add rehype-external-links @astrojs/markdown-remark | ||
| ``` | ||
| </Fragment> | ||
| </PackageManagerTabs> | ||
|
|
||
| 2. Configure the plugin in your `astro.config.mjs` file. | ||
|
|
||
| Import `unified()` and define it as the Markdown processor to [support remark plugins](/en/guides/markdown-content/#using-remark-and-rehype-plugins). Then, pass to `rehypePlugins` an array containing your imported `rehypeExternalLinks` plugin and an options object with a `content` property. Set this property's `type` to `text` if you want to add plain text to the end of the link. To add HTML to the end of the link instead, set the property `type` to `raw`. | ||
|
|
||
| ```js title="astro.config.mjs" | ||
| import { unified } from '@astrojs/markdown-remark'; | ||
| import { defineConfig } from 'astro/config'; | ||
| import rehypeExternalLinks from 'rehype-external-links'; | ||
|
|
||
| export default defineConfig({ | ||
| markdown: { | ||
| processor: unified({ | ||
| rehypePlugins: [ | ||
| [ | ||
| rehypeExternalLinks, | ||
| { | ||
| content: { type: 'text', value: ' 🔗' } | ||
| } | ||
| ], | ||
| ] | ||
| }), | ||
| }, | ||
| }); | ||
| ``` | ||
| </Fragment> | ||
| </PackageManagerTabs> | ||
|
|
||
| 2. Configure the plugin in your `astro.config.mjs` file. | ||
|
|
||
| Import `unified()` and define it as the Markdown processor to [support remark plugins](/en/guides/markdown-content/#using-remark-and-rehype-plugins). Then, pass to `rehypePlugins` an array containing your imported `rehypeExternalLinks` plugin and an options object with a `content` property. Set this property's `type` to `text` if you want to add plain text to the end of the link. To add HTML to the end of the link instead, set the property `type` to `raw`. | ||
|
|
||
| ```js title="astro.config.mjs" | ||
| import { unified } from '@astrojs/markdown-remark'; | ||
| import { defineConfig } from 'astro/config'; | ||
| import rehypeExternalLinks from 'rehype-external-links'; | ||
|
|
||
| export default defineConfig({ | ||
| // ... | ||
| markdown: { | ||
| processor: unified({ | ||
| rehypePlugins: [ | ||
| [ | ||
| rehypeExternalLinks, | ||
| { | ||
| content: { type: 'text', value: ' 🔗' } | ||
| } | ||
| ], | ||
| ] | ||
| }), | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| :::note | ||
| The value of the `content` property is [not represented in the accessibility tree](https://developer.mozilla.org/en-US/docs/Web/CSS/content#accessibility_concerns). As such, it's best to make clear that the link is external in the surrounding content, rather than relying on the icon alone. | ||
| ::: | ||
| </Steps> | ||
| </Steps> | ||
| </Fragment> | ||
| </MarkdownProcessorTabs> | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious. Before we initially said
rehype, which are the HTML plugins, and not remark, which are the Markdown plugins.Should the new copyright be generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, remark and rehype do not run with the same context, but I think this is our generic term at the moment:
But I see what you mean; it might be oversimplified and could be confusing for some... Maybe "Markdown processor plugins" would be better to talk of both. But, I'm not sure what to use to distinguish between the two.
I mean, I don't think I've ever seen "HTML plugins" being used to refer to "rehype plugins". Even before Sätteri, "hast plugins" would have been more meaningful to me as rehype plugins work on a hast tree.
I was looking what others use:
So, yeah, not sure what we should do here. 🤔
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider also that I come from a place where I learnt about the different between
remarkandrehypevery recently (during the Satteri migration), andunifiedwas meant join them together. I don't know the level of knowledge of the audience of the guide, but consider that there people like me that don't know anything about this ecosystem (or very little).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, I'm totally biased here (I also use nlcst so... 😄 ). I think this is a good call and not only for the recipes, but the Markdown guide as well! I might create a Discord thread tomorrow for some brainstorming, unless I have a flash of inspiration overnight...
What I have so far... (spoiler: not much)
For remark/mdast and rehype/hast:
As umbrella, for any plugin (this could include recma as well):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I haven't forgotten that, and I'm not sure I had a "flash of inspiration" 😆 but, I'm trying a different approach: update the Markdown guide first to perhaps find a better idea for a name. (#14297, WIP!) We have at least one outdated section and we'll need to update "Markdown plugins" there too...
I probably won't have much time to dedicate to it tomorrow though, so I'll continue next week.