Astro v5 to v7 Upgrade
- Published on:
- Categories:
- Astro 8, Process 10
- Current music:
- SARI —
mawaru
- Current drink:
- Infusion of hibiscus, apples, rosehip, and orange peels, with cherry flavor.
My blog runs on Astro, and I did not upgrade it in a while.
So, I decided to try going from 5.16.2 straight to 7.4.4. Not for any particular reason, but just to keep things fresh. This post documents what happened. In short: upgraded successfully, but with a few issues I had to solve during it.
The Issues
Most of the issues that I needed to solve were documented in some way on two pages of Astro docs:
Most things were straightforward, like those changes related to the Content Layer API, but there were a few undocummented suprizes.
Content Config Location
This is one of the simpler ones. The content config changes name and location: from src/content/config.ts to src/content.config.ts.
Explicit Loader
Previously, the defineCollection inside that config had an implicit loader inside, now you have to import it and use explicitly.
--- a/src/content/config.ts
+++ b/src/content.config.ts
-import { defineCollection, z } from 'astro:content';
+import { defineCollection } from 'astro:content';
+import { z } from 'astro/zod';
+import { glob } from 'astro/loaders';
const blog = defineCollection({
+ loader: glob({
+ pattern: '**/*.{md,mdx}',
+ base: './src/content/blog',
+ }),
The z import change was not required for now, just deprecated, but I made this fix as well to be more future-proof.
Front Matter and Indentation
The biggest blocker was this cryptic issue that appeared after updating the config location and content:
Flow map in block collection must be sufficiently indented and end with a } at line 9, column 2
The cause: previously, Astro seemed to be a bit more relaxed in how it parsed the YAML front matter. Well, that meant that I used tabs instead of spaces for indentation inside it. And, I learned, strict YAML does not understand tabs:
To maintain portability, tab characters must not be used in indentation, since different systems treat tabs differently.
Ugh. So… I had to go and update front matter in all my posts to use spaces instead of tabs. Oh well.
Updating the Slug-based IDs
The data entry type changed where previously it had a slug field, and now it is an id. Maybe there were some internal changes as well, but for my cases it seemed to be enough to adjust what I access when I wanted to change the posts’ slugs:
return posts.map((post) => ({
- params: { slug: betterSlug(post.slug) },
+ params: { slug: betterSlug(post.id) },
props: post,
}));
Updating the Post Renderer
Another thing I did not see in the migration guides is how you could render the content of some posts inside Astro components. I wrote about why I am doing this in my “Astro MDX Components” post, but the change was pretty straightforward:
--- a/src/pages/[...slug].astro
+++ b/src/pages/[...slug].astro
---
+import { render } from 'astro:content';
-const { Content } = await post.render();
+const { Content } = await render(post);
And, if I understand correctly, this also means that it is now possible to render post content this way in many more cases, which I will try to use in the future for rewriting how I do RSS for this blog.
Markdown Processor
In v7, Astro got a new Markdown processor.
As I was relying on the previous one, I had to make an adjustment:
--- a/astro.config.mjs
+++ b/astro.config.mjs
+import { unified } from '@astrojs/markdown-remark';
export default defineConfig({
markdown: {
+ processor: unified({
+ remarkPlugins: [ [remarkToC, {
+ heading: "table of contents",
+ } ] ]
+ }),
- remarkPlugins: [ [remarkToC, {
- heading: "table of contents",
- } ] ]
},
Basically, using an explicit processor with the old unified config, moving the remarkPlugins inside of it. Maybe I will need to look into if there is a ToC plugin for the new Rust-based Markdown processor, as it would be nice to get this speed buff.
Astro Component JSX and Whitespace
Final and very minor issue that I noticed was in how Astro now handles whitespace in JSX of Astro components: it now strips it fully, so I had to insert it manually in a few places:
--- a/src/components/Footer.astro
+++ b/src/components/Footer.astro
<a href="/rss.xml">RSS</a>
- ·
+ {' · '}
<a …
Another option would be to change the option back to compressHTML: true, but if I can make things work with the defaults, it feels better.
Non-Issue with Non-Standard Whitespaces
A related non-issue with that was that in a few places I was using non-standard spaces in code, like thinner spaces — when comparing with the live version of my blog, I found out that those were actually converted to regular spaces by Astro before, and now worked as intended. Nice!
That’s It
I think I might’ve missed some minor stuff I adjusted where noticed, like some type changes, but otherwise this seems to cover everything I had to do for the upgrade.
Aside from the YAML whitespace change, it was straighforward.