Plain Markdown is fine for prose, but tutorials usually need more: a warning that stands apart from the surrounding paragraph, or install steps that differ by package manager. Posts in src/content/posts can now be .mdx files, which means a post can drop in components alongside regular Markdown without any extra imports.

This article is itself an .mdx file, and every box below is real output, not a screenshot.

Callouts

Use <Callout> to flag something the reader shouldn’t skim past. The type prop picks the color and default label; title overrides the label if you need something more specific.

Tabbed code samples

Use <CodeGroup> with <CodeGroupItem> children to show the same step across a few variants, like package managers, without repeating the surrounding prose three times.

npm

npm install
npm run dev

pnpm

pnpm install
pnpm dev

yarn

yarn install
yarn dev

The tabs are progressive enhancement: a small inline script builds the tab list and hides the inactive panels on load. Without JavaScript, every panel still renders in order with a visible label, so the content stays readable either way.

Syntax highlighting

Ordinary fenced code blocks don’t need a component at all. Markdown and MDX posts both render through Shiki with a dual light/dark theme, so a plain code block already follows whichever color mode the reader has picked:

export function greet(name: string) {
  return `Hello, ${name}`;
}

Where the components live

Both components are plain .astro files in src/components/mdx, styled with the same tokens as the rest of the theme, so they pick up light and dark mode automatically. Add more the same way: build the .astro component, then make it available to posts through the components prop passed to <Content /> in src/pages/post/[slug].astro.