MDX Rendering with Astro

Date
Clock 5 min read
Tag
#astro#astro-rendering#mdx#static-sites
MDX Rendering with Astro

Where Article Rendering Actually Happens

The dynamic journal route eventually reaches one critical line.

<renderResult.Content components={components} />

This is the moment when an MDX file becomes HTML.

Earlier steps resolved the entry and loaded the compiled MDX module. That module exposes a render function.

A simplified version of the process looks like this.

const renderResult = await entry.render();

The returned object contains several properties.

renderResult ├── Content ├── headings └── frontmatter

Content is a component generated by the MDX compiler. Astro renders it like any other component.

MDX file Astro MDX compiler render() renderResult.Content HTML output

How Markdown Becomes HTML

MDX sits on top of Markdown. The rendering process begins by parsing Markdown tokens.

Example source.

## Section Title This is a paragraph. \`\`\`js console.log("hello"); \`\`\`

The Markdown parser converts this into tokens.

Heading token Paragraph token Code block token

The MDX compiler maps those tokens to HTML elements.

Heading token → <h2> Paragraph token → <p> Code block → <pre><code>

Astro wraps these elements inside the generated Content component.

Markdown Markdown tokens MDX compiler JS component HTML

This process happens during the build.


Custom Rendering Through Components

The components property allows overriding the default HTML mapping.

Without overrides.

## Title

Becomes.

<h2>Title</h2>

With overrides.

const components = { h2: HeadingAnchor, pre: CodeBlock, };

Rendering becomes.

<h2> → HeadingAnchor <pre> → CodeBlock

The MDX compiler uses this mapping while generating the page.

Markdown token Default HTML tag Override exists ├─ yes → custom component └─ no → normal HTML

This mechanism allows the project to introduce custom behavior without changing article content.


The Article Layout Component

All rendered content lives inside the article layout.

File.

src/components/sections/thejournal/Article.astro

This component wraps the rendered MDX.

Simplified structure.

<article class="journal-article"> <slot /> </article>

The slot receives the output of renderResult.Content.

renderResult.Content slot Article layout Styled HTML

The article layout does not transform the content. Its role is structural and stylistic.


The Typography System

The visual appearance of the article comes from a shared typography stylesheet.

File.

@styles/typography-bundle.css

The Article component attaches a class that activates these styles.

Example.

<article class="typography"> <slot /> </article>

The stylesheet defines rules for common elements.

Examples.

.typography h1 .typography h2 .typography p .typography pre .typography code .typography ul

This approach provides several benefits.

  • Markdown stays clean
  • Styling stays centralized
  • Articles remain portable
Article component Typography class CSS rules apply Styled headings paragraphs and lists

CodeBlock Component

Code blocks use a custom component. This component replaces the default pre rendering.

Typical responsibilities include.

  • syntax highlighting
  • copy button
  • language labels
  • scroll handling

Example override.

const components = { pre: CodeBlock, };

Rendering flow.

Markdown code fence Token type code block Mapped to CodeBlock Styled code container

Instead of raw HTML.

<pre><code>...</code></pre>

The page receives a richer component.


HeadingAnchor Component

Headings inside articles include anchor links.

Example source.

## Rendering Pipeline

Default HTML output would be.

<h2>Rendering Pipeline</h2>

The project replaces headings with a custom component.

const components = { h2: HeadingAnchor, h3: HeadingAnchor, };

This component adds a linkable anchor.

Example output.

<h2 id="rendering-pipeline"> <a href="#rendering-pipeline"> Rendering Pipeline </a> </h2>

Benefits include.

  • direct linking to sections
  • easier navigation
  • automatic heading ids
Markdown heading Heading token HeadingAnchor component Heading with anchor link

The Full Rendering Pipeline

Putting everything together.

MDX Article Astro Collection entry.render() renderResult.Content Component overrides ├── CodeBlock └── HeadingAnchor Article Layout Typography Styles Final HTML

The result creates a clear separation of responsibilities.

  • MDX files hold content
  • components handle behavior
  • CSS defines presentation
  • Astro compiles everything into static HTML

From the reader perspective the page loads instantly. Every heading, paragraph, and code block already exists when the page arrives.