Skip to content

Add a Sätteri tab in the remark/rehype recipes - #14277

Open
ArmandPhilippot wants to merge 14 commits into
mainfrom
armand/satteri-recipes
Open

Add a Sätteri tab in the remark/rehype recipes#14277
ArmandPhilippot wants to merge 14 commits into
mainfrom
armand/satteri-recipes

Conversation

@ArmandPhilippot

@ArmandPhilippot ArmandPhilippot commented Jul 18, 2026

Copy link
Copy Markdown
Member

Description (required)

Since Astro 7, Sätteri is the default Markdown processor, but our recipes were still using remark/rehype. This adds Sätteri/Unified tabs to them!

  • external-links.mdx: <Steps /> nested inside <Tabs /> as the content is different enough
  • modified-time.mdx and reading-time.mdx: <Tabs /> nested inside <Steps /> as the content is pretty similar (a bit annoying for the packages to install though)
  • Sätteri doesn't have a root visitor, so I worked around that. But, we might be able to use something else in the future: in Support root visitor on plugins bruits/satteri#164 Erika said a root visitor is planned for the next Sätteri minor!
  • The Markdown guide already use a syncKey for Unified/Sätteri, so I added a new <MarkdownProcessorTabs /> component to ensure this remains in sync. (AD² says "Other custom components may be added over time." so I don't think we need a PR there)

If you want to check/play with the plugins:

Note that git is not available on Stackblitz, so you'll need to download the repro, init Git, and make an initial commit.

In addition, I updated a few other things:

  • external-links.mdx: Removes the callout at the end as the statement is wrong. rehype-external-links does not use the CSS content property but a <span /> to inject the content (see https://www.npmjs.com/package/rehype-external-links#fields). So, the icon is in the accessibility tree. Now, I agree this is not the best for accessibility but it doesn't seem like we have control on the <span> (e.g. to set aria-hidden: true).
  • modified-time.mdx and reading-time.mdx, continuing my series on fixing code snippets issues:
    • <head>...</head> is formatted to <head></head>... so I added some content in there instead.
    • In "If you’re using a Markdown layout", <meta charset="utf-8" / > is expected since v5

@ArmandPhilippot ArmandPhilippot added the add new content Document something that is not in docs. May require testing, confirmation, or affect other pages. label Jul 18, 2026
@astrobot-houston

astrobot-houston commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
en/guides/markdown-content.mdx Source changed, localizations will be marked as outdated.
en/recipes/external-links.mdx Source changed, localizations will be marked as outdated.
en/recipes/modified-time.mdx Source changed, localizations will be marked as outdated.
en/recipes/reading-time.mdx Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown

Preview deployment

✅ Deployment complete!

import getReadingTime from 'reading-time';
import { defineMdastPlugin, type MdastNode } from 'satteri';

const findRoot = (

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is verbose compared to the remark version but, AFAIK, this is the best way in Sätteri; I've done the same thing when porting my website. Parsing ctx.source instead seems to work with Markdown files but this is not reliable with MDX (components, custom plugins).


export const mdastReadingTimePlugin = defineMdastPlugin({
name: "mdast-reading-time",
text(node, context) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if there is something better than the text() visitor here. Because it runs multiple times for the same file, we need to check if the frontmatter property is set to return early.

@ArmandPhilippot
ArmandPhilippot marked this pull request as ready for review July 21, 2026 13:37
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.

Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Member Author

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:

  • remark (unified) / mdast (Sätteri): plugins to control how Markdown files are parsed
  • rehype (unified) / hast (Sätteri): plugins to control the HTML output of Markdown files
  • unified plugins / Sätteri plugins: Markdown plugins

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:

  • Docusaurus uses "MDX plugins" to gather remark and rehype plugins
  • VitePress uses "Markdown extensions", but they use MarkdownIT so I'm not sure there is a concept like remark/rehype with it.

So, yeah, not sure what we should do here. 🤔

@ematipico ematipico Jul 22, 2026

Copy link
Copy Markdown
Member

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 remark and rehype very recently (during the Satteri migration), and unified was 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).

Copy link
Copy Markdown
Member Author

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:

  • "Markdown AST plugins" and "HTML AST plugins"
  • "Markdown tree plugins" and "HTML tree plugins"
  • "MDAST plugins" and "HAST plugins" (well... seems accurate to me, but then it might be confusing because that's how Sätteri call them, not unified)
  • "remark and mdast plugins" and "rehype and hast plugins" 😅

As umbrella, for any plugin (this could include recma as well):

  • Markdown processor plugins (would that be as confusing as "Markdown plugins" given this includes rehype/hast?)
  • Processor plugins (as long as this is only used in Markdown context, this could work)
  • Syntax tree plugins
  • AST plugins

Copy link
Copy Markdown
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

add new content Document something that is not in docs. May require testing, confirmation, or affect other pages.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants