Astro v2.0

In my continuing Astro saga, here’s the latest chapter. This post marks the completion of this site’s Astro v2 upgrade. Rather than explain how to upgrade because that already exists, this is more of my thoughts and impressions on how the upgrade went.

Since that last post where I said “I should work on a plugin for Astro + MiniSearch”, I went ahead and did that. At the end of January 2023, Astro v2 launched. One of the headline features was Content collections, something similar to Nuxt Content. If you consider .md files to be data and .astro files to be presentation, then keeping them separated makes tons of sense.

Although I didn’t have to use the new content collections, part of this site’s raison d’être is to understand and extend Astro, so I went for it. If it wasn’t for my search plugin, upgrading probably would have been fairly smooth. I think the Astro team did a phenomenal job once again of documenting how to do it and keeping breaking changes to a minimum. In particular, the “Migrating from File-Based Routing” section was clutch.

For the most part, things Just Worked. Things I like about Astro v2:

Not so great:

More detail about that last one. It’s cool to define collection schemas, but they are sort of generated at build time I guess? The documentation is still a little sparse, or maybe my use case is extreme. For this site, I have two content collections, blog and articles that I want to index for search. Both collections have a mandatory title attribute and an optional description. The documentation describes CollectionEntry class but it’s not clear how to use it.

In the end I sort of figured it out, but it’s not ideal. I used CollectionEntry<any> in my search indexer and defined a base search item schema with Zod. I used Zod’s extend method to “inherit” from a common set of searchable document fields. Instead, I wish there was a ContentEntry<"search"> type without requiring an empty “search” collection. Since I’m ignoring the type anyway there’s little purpose to the fancy schema. That may be a microcosm of TypeScript’s overall failures though.