Skip to content

Markdown and MDX Extended Features

A tour of the advanced markdown and MDX capabilities used in this site, including callouts, code fences, and embedded components.

This post showcases the extended markdown and MDX feature set enabled in this site. It is intentionally dense and varied, serving as both documentation and a regression suite for the content pipeline.

If you are updating the content schema, remark/rehype plugins, or MDX integration, this article is a good one to keep an eye on.


Basic markdown features#

Headings#

Markdown headings generate the document outline and feed into the table of contents:

# H1
## H2
### H3
#### H4

They are rendered with appropriate semantics (<h1><h4>) and are usable for navigation, screen readers, and SEO.

Emphasis and strong text#

*italic* and _italic_
**bold** and __bold__
***bold italic***

Be consistent with one style in prose—even though the renderer accepts both.

[Inline link](https://example.com)
[Reference link][example-link]
[example-link]: https://example.com

External links generally receive rel="noopener noreferrer" and target="_blank" for security and UX considerations.


Lists and nested content#

Unordered lists#

- One
- Two
- Sub-item
- Another sub-item
- Three

Ordered lists#

1. First
2. Second
3. Third

Lists can contain other markdown elements, including code blocks and nested lists.


Code fences and language hints#

Code fences support language hints for syntax highlighting:

```ts
export function add(a: number, b: number): number {
return a + b;
}
The language identifier (e.g. `ts`, `js`, `bash`, `json`) is used by the highlighter to apply appropriate tokens.
### Inline code
Inline code uses backticks:
```md
Use the `add` function for integer addition.

Rendered as: Use the add function for integer addition.


Tables#

Basic GitHub-style tables are supported:

| Feature | Supported | Notes |
| ---------- | --------- | ---------------------------- |
| Tables | Yes | Standard pipe syntax |
| Alignment | Yes | Use `:` for left/right/center |
| HTML | Limited | Prefer markdown where possible |

Tables are rendered as <table>, <thead>, and <tbody> elements for semantic correctness.


Images#

Standard markdown images:

![Alt text for accessibility](/images/blog/markdown-example.png)

For better control over layout or optimization, use Astro or framework components in MDX files instead of raw markdown images.


Callouts and admonitions#

Callouts are implemented as custom markdown blocks or MDX components (depending on configuration). For example, you might have something like:

> [!INFO]
> This is an informational callout.
> [!WARNING]
> This is a warning callout.

Or, in MDX, a dedicated component:

<Callout type="info">
This callout is powered by MDX components.
</Callout>

The exact syntax depends on the remark/rehype plugins and components wired into your pipeline, but this post is structured to exercise both patterns.


MDX specifics#

This section is relevant primarily for .mdx files. If this document is saved as .md, the JSX examples serve purely as code samples; if it is .mdx, they may be rendered as live components.

Importing components#

import { Callout } from '~/components/blog/Callout';
import { Counter } from '~/components/blog/Counter';

Using components in content#

<Callout type="tip">
MDX is especially useful when you want to **mix prose with interactive UI**.
</Callout>
<Counter initial={1} />

Where Counter might be defined as:

type CounterProps = {
initial?: number;
};
export function Counter({ initial = 0 }: CounterProps) {
const [value, setValue] = useState(initial);
return (
<div className="counter">
<button type="button" onClick={() => setValue((v) => v - 1)}>-</button>
<span>{value}</span>
<button type="button" onClick={() => setValue((v) => v + 1)}>+</button>
</div>
);
}

This is not meant for production in this file, but it demonstrates that interactive components can be embedded when needed.


Shortcodes and custom syntax#

If you have remark plugins configured for shortcodes, this post is a good target for those. Example pseudo-syntax:

:::note
This is a note rendered via a custom container.
:::
:::warning
This is a warning rendered via a custom container.
:::

Alternatively, you can use MDX components to achieve the same effect with more explicit semantics.


Footnotes#

If footnote support is enabled:

Here is a sentence with a footnote.[^1]
[^1]: This is the footnote content.

Footnotes are rendered at the end of the article and are linked bidirectionally via anchors.


Task lists#

Task lists render as checkboxes:

- [x] Migrate frontmatter to new schema
- [x] Validate markdown rendering
- [ ] Add more MDX examples

They should be accessible and navigable via keyboard.


Escaping and literal characters#

Use backslashes to escape characters that markdown would otherwise interpret:

Render a literal asterisk: \*

This is useful when discussing raw markdown syntax or regex patterns.


Putting it all together#

This article intentionally combines:

  • Rich frontmatter (dates, tags, hero image)
  • Extensive markdown primitives (headings, lists, links, tables)
  • Code fences in multiple languages
  • Optional MDX features (imports, components, callouts)
  • Footnotes and task lists (if enabled)

so that changes to the content configuration, MD/MDX pipeline, or blog layout are likely to surface as visible regressions here.

If this post renders correctly, it is a strong indication that the extended markdown and MDX feature set is wired up as intended.