What I did
I just rebuilt my quarter-century blog with Astro! Well. There’s neglected corners and ideas I have not yet implemented. Enough of it works that I feel comfortable posting it anyways. It is a personal site. Perfect is the enemy of the “ehh, good enough.”
“Under construction icon-red” by AnonymousUnknown author is licensed under CC BY 3.0.
Why
Hugo has been generating this site for nearly ten years. It’s fast, flexible, and occasionally maddening. But every once in a while I need to stretch myself in new directions. It’s been a couple years since my last experiment, when I tried out Eleventy.
This time around I want something still mostly static but with a clearly defined path to add dynamic behavior later should I want it. Also, components seem nice. So we’re using Astro.
How
Not a full playthrough, just highlights of integrations and dependencies.
Markdoc
Markdoc is basically a shortcode extension for Markdown. It supports named tags along with extending the behavior of core nodes. You know: links, blockquotes, fenced code blocks.
It seems nifty, and for the most part it has been. I picked Markdoc to reduce cognitive load when translating from Hugo’s shortcode-based templating. The nice part is that you can tie those shortcodes directly to Astro components.
Say you have a <Video />
component.
---import { YouTube } from "astro-embed"
interface Props { id: string}
const { id } = Astro.props---<YouTube {id} />
<style> lite-youtube { margin: 1rem auto; }</style>
You configure a Markdoc tag to render that component.
import { defineMarkdocConfig, component } from "@astrojs/markdoc/config";
export default defineMarkdocConfig({ tags: { video: { render: component("./src/components/Video.astro"), attributes: { id: "string", }, }, },};
Then use that tag in your Markdoc.
Share the deep thoughts on your page.
{% video id="1injh4-n1jY" /%}
Share the deep thoughts on your page.
MDX
Astro only supports Markdoc in content collections. That meant adding MDX integration to support Markdown + components outside of posts. Maybe I should be using MDX instead of Markdoc?
Expressive Code
Expressive Code provides syntax highlighting for many languages, with many niceties. You can give your code blocks a title. That’s why I grabbed it. But it also provides a widget for copying code to the clipboard, distinct framing for code files vs shell interactions, line markers, and more. And “more” can go even further since it provides hooks for themes and plugins.
Honorable mentions
- Astro Breadcrumbs for those little trails back to the top of the site
- Astro Embed for YouTube videos
- the Astro recipe for RSS feeds; I need to load my own Markdown handler if I want full-content feeds?
- Vitest and @astrojs/check for automated quality checks; not much in my tests yet, but had to be ready for later
Initial impressions
This isn’t my first time playing with Astro, but it is the first time I’ve rebuilt the whole site with it. I gave it a heck of a try around the time of my Eleventy experiment. There were too many inconsistencies in frontmatter and content. Fortunately I spent the last couple months streamlining and enforcing enough consistency that a full port is practical now.
What’s been nice
TypeScript for site-building logic is significantly more pleasant than using some template language for the task.
Astro’s documentation is better than most, in terms of what it covers, the density of useful information, and how it’s presented. This encourages similar documentation practices for community integrations.
It’s nice to have access to NPM. Whatever problem I’m trying to solve, somebody has already thought halfway through it. And they published it with instructions on a pretty documentation site, too. For the Astro-specific stuff, at least.
Astro has more explicit paths than something like Eleventy. That’s both a pro and a con. It means you know where to go once you understand the hooks. It also means anything beyond that is unmapped territory. In Eleventy, since everybody’s (basically) building their own trail, there’s a lot more guidance on trail-building.
Most of all, I enjoy component-based design. There’s this whole layer of encapsulation I have missed on the design side of Web stuff. The styles for each component are right there next to the markup, but it’s still CSS.
What’s been less nice
Way too many workarounds. The integrations I tried shared a pattern of looking more polished than they actually were. A very “enterprise software” mental impression, that is.
I’m being unfair. I shouldn’t compare anything to enterprise software. The issue is like I mentioned with the Eleventy comparison: once you step off the golden path, the docs won’t help you. You’ll be searching community forums and site repos for some kind of clue.
Markdoc is convenient, but I keep bumping into rough edges with its Astro integration. Markdoc itself does not support Markdown definition lists, a syntax to generation HTML description lists. This cramps my style.
I can see a path where I swap out Markdoc for MDX and some custom Remark extensions.
Overall
Astro is pleasant to use even with its occasional sharp edges. I did spend an awful lot of time thinking “this bit’s easier in Hugo / Eleventy / Nanoc.” Maybe this is not for you if you already have a workflow that makes you happy.
What’s next
I want to make this old site shiny and fun to play with. Got all sorts of ideas. Dynamic features. Interactivity. Subscription popups. Okay no. Not subscription popups.
Next I should work on the tests though. I had this whole suite of tests for the Hugo site. Stuff like linting Markdown, validating schemas, and checking internal links. I’ve started that here. Need to continue building those up, and expand them further.
Probably worth doing a few writeups about.
Feels good to be having fun with my site.