Early 2025, I announced the launch of this new website. I shortly mentioned my technical choices. Here, I’d like to bring a little more details.

A static website built with Astro

This website is content-oriented and doesn’t require a lot of updates client-side. Generating a static website therefore seems more appropriate than an website rendered on demand.

Decision drivers

Here a list more or less exhaustive of the features I wanted :

  • a contact form,
  • a search form with an index generated at build time,
  • several RSS feeds,
  • i18n support,
  • managing contents with Markdown (.md and not .mdx preferably), including frontmatter support (in YAML format for portability),
  • extend the Markdown syntax with remark/rehype if needed,
  • customize the rendering of Markdown elements,
  • separate the website source code from the contents,
  • include user settings (ie. changing theme),
  • offers a comments area.

I also wanted the site to work without Javascript and not have more scripts than necessary. So, I excluded Next.js that I was using with my previous website.

Considered options

Among the most popular solutions, there are Hugo and Jekyll of course. I still wanted to explore the other possible choices with the help of the Jamstack website. The list is pretty long so I haven’t looked at everything. The projects that seemed most interesting to me were Zola, Astro, Nikola, Metalsmith, Pelican, and Hexo.

Decision outcome

After comparing the features I wanted to use and what the different SSGs offered, I chose to use Astro with Pagefind to deal with the search results.

Astro seemed to be the only one that met all of my needs, or almost. I haven’t implemented a comment area yet, but I know it’s something possible. The only point I haven’t resolved is the use of .md instead of .mdx to write my contents while customizing the rendering.

Regarding the components that require a bit of interactivity like the contact form, I chose to use custom elements instead of a framework even if it’s possible with Astro !

Managing the contents

My starting wish

I wanted portable contents editable from any text editor. Markdown seems to me to be a good choice. With the help of the unified ecosystem, I can extend the syntax to answer my editorial needs. From this observation, I thought I could avoid MDX and use the .md extension for my contents.

Some issues

Astro supports the use of a components property while using <Content /> to map some components to elements. However, this only works with MDX. There are some discussion around this topic (especially the ones opened by noghartt and by wassfila) but I doubt it will ever be possible.

Likewise, since Markdown is directly rendered as HTML, it doesn’t seem possible to inject a component using remark or rehype. At least, I haven’t found a way to do that yet. MDX, in another hand, is rendered as JSX; It is therefore possible to do this to avoid importing components into the content.

My decision

So I chose to use MDX for now without actually using MDX: any written content can be copied/pasted into a Markdown file without any compatibility issues (I don’t use imports or variable declarations). That said, I will continue to look for a solution.

Between the start of the project and the current version (v1.0.3), I moved some styles declared in the components to the global scope. With this change, I reduced the number of components defined in the components property. However, I can’t do without all the mapping unless I get a little more verbose in my files and move even more styles around.

There is also the problem of injected components. Currently the only component I inject using Rehype is for my code blocks. I can find another solution I guess… We’ll see!

Deployment

In my decision drivers, I mentioned that I wanted to separate my source code from my contents. I achieved that by:

  • declaring the contents directory path as an environment variable
  • creating a second repository housing my contents and the website source code as a Git submodule.

I have some cache (or routing) issues when I run the dev command in the second repository. So the solution is not perfect, but I’m fine with that. I don’t need the server when I’m writing. I only use it at the end to check the rendering.

In this second repository, I’m using Docker to build an image of the website before pushing it to a private registry. Then, on my VPS, all I need to do is to fetch the image and to update my container.

TL;DR

This website is built with the help of Astro (using vanilla CSS/JS and some custom elements), Pagefind, MDX and Docker and I’m pretty satisfy with the result! Well, I say vanilla JS but I mostly use Typescript.