Creating a blog platform with Astro and MDX
TLDR: source code can be found here
Ever since I started blogging, I wanted to do this on my personal website thomasledoux.be. Since it seemed rather difficult to set up Markdown/MDX support in Remix & Next.js (the 2 frameworks I use for my website before), I chose to write my blogs at dev.to instead. This worked really well for a while, but now I want to have more control over my blog’s layout, analytics and to have MDX support. So I started building my own blog platform, and chose to do this with Astro!
Setting up Astro
Setting up Astro is very easy.
You can just run
npm create astro@latest in your terminal, follow the steps, and you’ll have your project up and running in seconds.
Once your Astro project’s set up, the next thing we’ll do is adding MDX support.
You can add MDX support through an Integration in Astro.
This is as easy as running
npx astro add mdx in your terminal.
Creating MDX blogs
Once the MDX integration is installed, you can start using MDX components and pages in your application.
You can get started by adding a folder
/blog in the
Inside this folder you then create your
.mdx files, for example
At the top of your MDX files, you can add
You can set up a
layout, which will make your blog’s content get rendered inside of the given
frontmatter properties you can also add custom properties, like
This will look like:
These properties will be available to use when you import the MDX component/page in another component/page, or when you use
Astro.glob() to read MDX files from the filesystem.
Your can use this a blog overview page to display the title, creation date and tags from the blog.
Adding reading time for blog posts
Astro makes it easy to add Remark or Rehype plugins to your markdown.
You can extend add a
markdown property to the Astro config file, an add a function/plugin to the
remarkPlugins property (the
extendDefaultPlugins property is added to make sure the default plugins aren’t overwritten by this config change):
./src/utils/calculate-reading-time.mjs file will look like this:
So you’d use 2 external libraries
mdast-util-to-string to make this work. Don’t forget to
npm install these!
Adding this to the Astro config, makes this data available in the
frontmatter of all your MDX files.
You can now start using this in our blog overview from earlier:
Setting up SEO (meta tags, og:image)
Because we are defining a
layout to be used on our MDX pages, we can start using the
frontmatter properties of the MDX page inside the
layout because they are passed in the
frontmatter properties can then be used to add something like a
<title> and an og:image
Note that in the example I’m using an API route of a different domain, this is because I’m using the
@vercel/og package to generate the
og:image based on the title of my blog post. You can read the docs here.
I also added some sparkles to the background, based on the example provided by Vercel.
The code for the
og:image generation looks like this (created inside a Next.js API route on my Next.js site):
I’m using the
Inter font, so if you want to use this too, make sure to download the font files and include them in your project.
And that’s it, my blog is now hosted on my own site! Go check it out at https://www.thomasledoux.be/blog. In a next blog article, I’ll dive deeper into how I added a system for comments on blogs, and analytics using Prisma and Planetscale for the DB stuff.