How I migrated this blog from Gatsby to Next.js
I know. I know. The previous post on this blog — from 2018, which is apparently a thing that happens to drafts folders — was me explaining, with total confidence, why making this blog a React app was the future. I stand by half of it. The React half. The other half has to go, and the other half is Gatsby.
What happened
In March I sat down to finally write the interactive sorting-algorithms post (it's still happening, the demo is 80% done) and started with a routine npm update. That update broke gatsby-plugin-sharp, which broke gatsby-transformer-sharp, which broke the build, at the end of which my terminal suggested — and this is real — that I delete .cache and node_modules and reinstall. The Gatsby cache-deletion ritual is so standard it should ship as an npm script. It is the have you tried turning it off and on again of the JAMstack.
And the GraphQL layer. Two years on, I must confess what every Gatsby blogger knows in their heart: I run a query language over my filesystem to retrieve one Markdown file. When I added a reading-time field it took me 45 minutes of schema customization. Reading time of the post: 4 minutes.
Enter Next.js
Next.js is just React. A page is a file. A route is a folder. Data fetching is a function. There is no plugin for reading the filesystem because reading the filesystem is something programs can simply do:
// No GraphQL. No resolvers. No schema. Just... reading the file.
const post = fs.readFileSync('content/post.md', 'utf8');The inventory, as required by the genre:
- Statically exported at build time — same HTML-files-on-a-CDN endgame as every engine since 2013, but with hooks.
- Build time: 94 seconds → 8 seconds. Numbers nobody asked for, provided free of charge, as is tradition.
- Deployed to Vercel on push. The preview-deployment-per-PR flow is genuinely excellent. I am the only person who opens PRs to this blog, and I approve them, but the option to discuss is there.
- One casualty to report: the RSS feed did not survive this migration. Both subscribers have been notified by email. I will rebuild the feed in a follow-up post (the follow-up post is also where the dark mode is happening).
Permalinks remain /year/month/title/, unbroken since 2009. Eleven years. Four engines. The URLs are the only part of this blog with a retention problem of zero.
The plan from here
And that's really it — that's the whole migration. No plugins, no cache rituals, no schema. The blog is finally boring, in the way infrastructure should be. Which means there are no excuses left between me and the writing. Sorting algorithms post: October. Hold me to it.
— Olav