Upgrading Astro to Version 5
by
Upgrading Astro is usually a great experience due to the vast tooling available. There are separate upgrade guides available and there even exists an upgrade tool that takes care of the necessary package dependency upgrades. Let’s run that.
npx @astrojs/upgrade
astro Integration upgrade in progress.
◼ @astrojs/check is up to date on v0.9.4
◼ @astrojs/sitemap is up to date on v3.2.1
● @astrojs/rss will be updated from v4.0.9 to v4.0.11
▲ astro will be updated from v4.16.16 to v5.2.3
▲ @astrojs/mdx will be updated from v3.1.9 to v4.0.8
▲ @astrojs/netlify will be updated from v5.5.4 to v6.1.0
▲ @astrojs/react will be updated from v3.6.3 to v4.2.0
I also ran a full dependency upgrade to move to React 19 using npx npm-check-updates -u
which worked surprisingly well.
That was only the first step, though. https://docs.astro.build/en/guides/upgrade-to/v5/ tells us that Astro now uses vite
v6.0 and that comes with it’s own set of breaking changes. I had to get rid of the @vite-pwa/astro
, simply because it doesn’t seem to support Astro v5 yet. I’m not using most of the PWA features and the manifest can be added manually.
No more hybrid
mode
We now only have static
and server
modes and we can opt out from static renderin any time which is a great improvement.
The Content Collections API is now considered “legacy”
This is by far the biggest change for me, I knew this was coming and it was surprisingly easy to move to the new Content Layer API, which is supposed to be faster, more versatile and hopefully longer lasting than the old one. I follwed the steps outlined in the guide.
- Moving the
src/content/config.ts
file tosrc/content.config.ts
. - Replacing
type: 'content'
with the loader pattern incontent.config.ts
.loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog" }),
- Replace the use of
post.slug
withpost.id
wherever I load posts. - Replace
post.render()
withrender(post)
as posts are now plain objects without a render method.
For the sake of future me I did all that, knowing that I didn’t have to, because there is a legacy mode available.
I noticed that my custom slugs still work. I used the slug
frontmatter field for that and now Astro automatically picks that as id
overwrite. Lucky me! One thing to keep in mind is that the content loader does not guarantee the same order of entries as the legacy loader, so sorting is always a good idea.