KKMIN

Some Upgrades to this Blog

It's been about one week since I built this blog; in the process of writing the previous post, I was reaching the limits in terms of what I could do with the content in a blog post.

Previously, I was simply parsing the content of Markdown files and displaying it on a dynamically generated page. While this works fine for pure text content, I was unable to do things like embed images, which was important for the previous post.

Initial Thoughts

My first thought, of course, was to simply embed HTML image tags in the Markdown file, or to use the Markdown syntax to attempt to link my images.

HTML Tags:


<img src='image_link' alt='img_desc'/>

Markdown Syntax:


![image_desc](image_link)

Unfortunately, it doesn't work and ends up just embedding the alt text as an image instead of the image itself, like this:

image_desc

I needed a different tool render my pages instead of just parsing .md files into HTML expressions, and the solution was MDX.

MDX

I got more than what I expected, as MDX allows us to integrate JSX expressions with Markdown! This means that we are able to write JSX code straight into a .mdx file, and embedding images becomes:


import Image from 'next/image';
import my_image from 'path';
# Markdown content
<Image src={my_image} alt='image_desc'/>

And it is not just limited to Images. For example, I can embed custom React components seamlessly in the .mdx file like this:

spinner

Click me!

This creates a great writing experience and also opens up a lot of creativity in blog posts. In many ways, this reminds me of JSX itself where it integrated Javascript with Markup language. MDX integrates JSX itself with Markdown for a coherent writing experience when using React components in the content.

In addition, MDX also allows us to do custom-styling for common Markdown elements like Headers; you can see that the h2 headers in this blog post are orange.

Metadata

MDX provides a default way to export the meta data of the post by exporting a Javascript object containing metadata which can be exported:


export const meta = {
title: 'Post title',
date: 'post date',
/*other metadata */
}

This object can then be used however you wish, for example in a layout component. However, I felt that this looked pretty inelegant in comparison to YAML frontmatter:


---
title: Post title
date: 'post date'
---

We can use gray-matter to parse the frontmatter to use in pages like our Home page to display the list of all our available blog posts. However, this poses a slight problem: the frontmatter ends up getting rendered as content on the page. This happens because our MDX compiler does not recognize YAML frontmatter by default.

Plugins

The remark ecosystem has a variety of plugins for Markdown related enhancements, and remark-frontmatter allows us to configure our MDX compiler so that it recognizes YAML frontmatter and ignore the content.

For syntax highlighting, the rehype-highlight plugin allows highlighting of our code blocks.

Remark vs Rehype?

Remark is a processor Markdown, whereas Rehype is a processor for HTML. There seems to be quite a bit of overlap between these two processors, and for some purposes both seem to work just as well. Both work on similar principles by modifying the Abstract Syntax Tree (AST), see here for more info.

Closing Thoughts

All in all, integrating MDX was a worthwhile upgrade; being able to seamlessly embed React components is really powerful and I look forward to using it for subsequent posts here.

For now, a headless CMS isn't really necessary and avoiding it might be better, as using local .mdx files allows me to see real time changes, especially for custom components with low turnaround time.

← Back to home

Comments