Building a Modern Blog with MDX, KaTeX, and Custom Components

mdxkatexreacttutorialweb-development

If you're building a technical blog or portfolio, you'll quickly realize that plain Markdown isn't enough. You need mathematical equations, interactive components, and the flexibility to extend your content beyond static text. In this tutorial, I'll show you how to combine MDX, KaTeX, and custom React components to create a powerful content authoring system.

What is MDX and Why Should You Care?

MDX is Markdown on steroids. It lets you seamlessly integrate JSX (React components) directly into your Markdown files. This means you can write regular Markdown for text, then drop in interactive components wherever you need them.

Here's why this matters:

  • πŸ“ Keep the simplicity of Markdown for writing
  • βš›οΈ Use React components for complex interactions
  • πŸ”§ Build reusable content blocks
  • 🎨 Create custom layouts without leaving your content

Let me show you how it works in practice.

Setting Up Math Rendering with KaTeX

For technical writing, especially in fields like physics, engineering, or computer science, mathematical notation is essential. KaTeX is a fast, lightweight math typesetting library that renders LaTeX math equations beautifully on the web.

Inline Mathematics

You can write inline math by wrapping LaTeX expressions in single dollar signs. For example, when discussing energy-mass equivalence, you might write: "Einstein showed that E=mc2E = mc^2, where EE is energy, mm is mass, and cc is the speed of light."

The Pythagorean theorem can be expressed as a2+b2=c2a^2 + b^2 = c^2 for a right triangle with sides aa and bb, and hypotenuse cc.

When working with complex numbers, Euler's formula relates exponentials to trigonometric functions in a beautiful way.

Display Mathematics (Block-Level)

For more complex equations that deserve their own space, use double dollar signs. This creates a centered, display-style equation:

The Quadratic Formula - Essential for solving second-degree polynomials:

x=βˆ’bΒ±b2βˆ’4ac2ax = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

Euler's Identity - Often called the most beautiful equation in mathematics, connecting five fundamental constants:

eiΟ€+1=0e^{i\pi} + 1 = 0

The Gaussian Integral - Fundamental in probability theory and quantum mechanics:

βˆ«βˆ’βˆžβˆžeβˆ’x2dx=Ο€\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}

Maxwell's Equations - The foundation of classical electromagnetism:

βˆ‡β‹…E=ρΡ0βˆ‡β‹…B=0βˆ‡Γ—E=βˆ’βˆ‚Bβˆ‚tβˆ‡Γ—B=ΞΌ0J+ΞΌ0Ξ΅0βˆ‚Eβˆ‚t\begin{align} \nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \\ \nabla \cdot \mathbf{B} &= 0 \\ \nabla \times \mathbf{E} &= -\frac{\partial \mathbf{B}}{\partial t} \\ \nabla \times \mathbf{B} &= \mu_0\mathbf{J} + \mu_0\varepsilon_0\frac{\partial \mathbf{E}}{\partial t} \end{align}

SchrΓΆdinger Equation - The fundamental equation of quantum mechanics:

iβ„βˆ‚βˆ‚tΞ¨(r,t)=H^Ξ¨(r,t)i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \hat{H}\Psi(\mathbf{r},t)

where H^=βˆ’β„22mβˆ‡2+V(r)\hat{H} = -\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r}) is the Hamiltonian operator.

Organizing Your Content Assets

One challenge with content-heavy blogs is asset management. I recommend organizing each post in its own directory with dedicated subdirectories for different asset types:

content/posts/my-post/
  β”œβ”€β”€ index.mdx          # Your main content
  β”œβ”€β”€ images/            # Screenshots, diagrams, figures
  β”œβ”€β”€ files/             # Downloadable files (code, datasets, PDFs)
  └── assets/            # Other media (videos, audio, etc.)

This structure keeps everything organized and makes referencing assets simple:

![Diagram explaining the concept](./images/concept-diagram.png)
[Download the MATLAB script](./files/simulation.m)

Combining Code and Mathematics

One of MDX's superpowers is seamlessly switching between code, math, and prose. Here's an example showing a numerical implementation alongside its mathematical foundation.

Problem: Solve the quadratic equation ax2+bx+c=0ax^2 + bx + c = 0

Mathematical Solution:

x1,2=βˆ’bΒ±b2βˆ’4ac2ax_{1,2} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

where the discriminant Ξ”=b2βˆ’4ac\Delta = b^2 - 4ac determines the nature of the roots.

Implementation in JavaScript:

/**
 * Solves a quadratic equation axΒ² + bx + c = 0
 * @param number a - Coefficient of xΒ²
 * @param number b - Coefficient of x
 * @param number c - Constant term
 * @returns Object containing roots and their nature
 */
function solveQuadratic(a, b, c) {
  // Calculate discriminant
  const discriminant = b * b - 4 * a * c;
  
  if (discriminant > 0) {
    // Two distinct real roots
    const x1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    const x2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    return `{` roots: [x1, x2], nature: 'real and distinct' `}`;
  } else if (discriminant === 0) {
    // One repeated real root
    const x = -b / (2 * a);
    return `{` roots: [x], nature: 'real and equal' `}`;
  } else {
    // Complex conjugate roots
    const realPart = -b / (2 * a);
    const imaginaryPart = Math.sqrt(-discriminant) / (2 * a);
    return `{` 
      roots: [
        `{` re: realPart, im: imaginaryPart `}`,
        `{` re: realPart, im: -imaginaryPart `}`
      ], 
      nature: 'complex conjugate' 
    `}`;
  }
}

// Example usage
console.log(solveQuadratic(1, -3, 2));  // xΒ² - 3x + 2 = 0
// Output: `{` roots: [2, 1], nature: 'real and distinct' `}`

Notice how we can discuss the mathematical theory and immediately show the practical implementation. This is incredibly powerful for educational content.

Advanced KaTeX Features

KaTeX supports a wide range of LaTeX features. Here are some advanced techniques:

Matrices and Vectors

Rotation matrix in 2D space:

R(ΞΈ)=[cosβ‘ΞΈβˆ’sin⁑θsin⁑θcos⁑θ]\mathbf{R}(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}

State vector in quantum mechanics:

∣ψ⟩=(αβ),∣α∣2+∣β∣2=1|\psi\rangle = \begin{pmatrix} \alpha \\ \beta \end{pmatrix}, \quad |\alpha|^2 + |\beta|^2 = 1

Summations and Products

Fourier series representation:

f(x)=a02+βˆ‘n=1∞(ancos⁑nΟ€xL+bnsin⁑nΟ€xL)f(x) = \frac{a_0}{2} + \sum_{n=1}^{\infty} \left(a_n \cos\frac{n\pi x}{L} + b_n \sin\frac{n\pi x}{L}\right)

Taylor series expansion:

ex=βˆ‘n=0∞xnn!=1+x+x22!+x33!+β‹―e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots

Piecewise Functions

The Heaviside step function:

H(x)={0ifΒ x<012ifΒ x=01ifΒ x>0H(x) = \begin{cases} 0 & \text{if } x < 0 \\ \frac{1}{2} & \text{if } x = 0 \\ 1 & \text{if } x > 0 \end{cases}

Creating Comparison Tables

Tables are great for comparing features, specifications, or results. MDX fully supports GitHub Flavored Markdown tables:

FeatureMarkdownMDXMDX + KaTeX
Text formattingβœ…βœ…βœ…
Images & linksβœ…βœ…βœ…
Code blocksβœ…βœ…βœ…
Math equationsβŒβŒβœ…
React componentsβŒβœ…βœ…
Interactive elementsβŒβœ…βœ…
Custom layoutsβŒβœ…βœ…
SyntaxPurposeExample
$...$Inline math$E = mc^2$
$$...$$Display math$$\int_0^1 f(x)dx$$
<Component />JSX component<CustomCard />
`code`Inline code`const x = 5`

Best Practices I've Learned

Through building this blog system, here are some key insights:

1. Separate Content from Presentation

Keep your MDX files focused on content. Use custom components for complex UI elements rather than mixing HTML into your Markdown.

2. Use Semantic Math

When writing equations, think about readability. Use \text for text within math mode, proper spacing with \quad and \,, and meaningful variable names.

3. Optimize Asset Loading

Images can slow down your blog significantly. Use Next.js Image optimization, WebP format, and lazy loading. Store assets close to your content for better organization.

4. Test Your Math Rendering

KaTeX doesn't support 100% of LaTeX. Test complex equations and have fallbacks. Some advanced LaTeX packages won't workβ€”know the limitations.

5. Make Content Portable

Even though you're using MDX, keep the Markdown core clean. This makes migration easier if you ever switch platforms.

What's Next?

Now that you understand the basics, you can:

  • Build custom components for your specific use case (interactive demos, data visualizations, etc.)
  • Create reusable content blocks (callouts, code sandboxes, embedded demos)
  • Add syntax highlighting with libraries like Prism or Highlight.js
  • Implement reading time estimation and table of contents generation
  • Add meta tags and SEO optimization for each post

The combination of MDX and KaTeX gives you incredible flexibility. You can write technical content that rivals traditional LaTeX documents while maintaining the interactivity and modern UX of a web application.

Conclusion

Building a content system with MDX and KaTeX might seem complex at first, but the power it gives you is worth the initial setup. You can write beautiful mathematical equations, embed interactive components, and maintain clean, readable content files all at once.

The key is understanding that you're not just writing blog postsβ€”you're building a system for creating rich, interactive technical content. And once you have that system in place, creating new content becomes both powerful and enjoyable.

Happy writing! πŸš€


Tech Stack: This blog uses Next.js 14, MDX, KaTeX, TypeScript, and Tailwind CSS. Each post lives in its own directory under content/posts/[slug]/index.mdx with dedicated folders for images, files, and assets.

  • Build custom components for your specific use case (interactive demos, data visualizations, etc.)
  • Create reusable content blocks (callouts, code sandboxes, embedded demos)
  • Add syntax highlighting with libraries like Prism or Highlight.js
  • Implement reading time estimation and table of contents generation
  • Add meta tags and SEO optimization for each post

The combination of MDX and KaTeX gives you incredible flexibility. You can write technical content that rivals traditional LaTeX documents while maintaining the interactivity and modern UX of a web application.

Conclusion

Building a content system with MDX and KaTeX might seem complex at first, but the power it gives you is worth the initial setup. You can write beautiful mathematical equations, embed interactive components, and maintain clean, readable content files all at once.

The key is understanding that you're not just writing blog postsβ€”you're building a system for creating rich, interactive technical content. And once you have that system in place, creating new content becomes both powerful and enjoyable.

Happy writing! πŸš€


Tech Stack: This blog uses Next.js 14, MDX, KaTeX, TypeScript, and Tailwind CSS. Each post lives in its own directory under content/posts/[slug]/index.mdx with dedicated folders for images, files, and assets.