fix: replace /, and/ with /and/

This commit is contained in:
Lorenzo Iovino 2026-01-28 17:41:28 +01:00
parent 4cb137ac45
commit f160d40c66
10 changed files with 72 additions and 59 deletions

View file

@ -1,6 +1,6 @@
---
title: "From Angular to Astro: building a cheap (and fast) personal site with a blog"
description: "I rewrote my website from Angular to Astro to have a Markdown blog with no backend, keep hosting costs low, and chase the four green Lighthouse scores."
description: "I rewrote my website from Angular to Astro to have a Markdown blog with no backend, keep hosting costs low and chase the four green Lighthouse scores."
pubDate: 2026-01-09
heroImage: "../../assets/photos/from-angular-to-astro/cover.png"
tags: ["astro", "aws", "seo", "performance", "ai", "migration"]
@ -12,7 +12,7 @@ import hostingDiagram from '../../assets/photos/from-angular-to-astro/hosting-di
I like technical challenges.
I know Angular very well, and I used React a lot too. So at some point I wanted to try something different, and people kept telling me: "look at [Astro](https://astro.build/)".
I know Angular very well and I used React a lot too. So at some point I wanted to try something different and people kept telling me: "look at [Astro](https://astro.build/)".
The main goal was simple:
@ -24,7 +24,7 @@ So… I rewrote my site. Angular SPA → Astro static site.
## Why Astro (for me)
For a personal website, most pages are content. Not "app".
For a personal website, most pages are content. Not "app".
And for content, static generation is just great:
- fast pages
@ -38,8 +38,8 @@ Astro also gives you a nice middle ground: you can keep the site mostly static,
I'm going to be super honest: I used an AI agent to do a big part of the work.
I read the Astro docs (just enough), then I basically jumped into development using AI, staying quite "high level".
I was more like a product owner: I described what I wanted, then I reviewed what the AI generated, and I fixed the parts where it got lost.
I read the Astro docs (just enough), then I basically jumped into development using AI, staying quite "high level".
I was more like a product owner: I described what I wanted, then I reviewed what the AI generated and I fixed the parts where it got lost.
This workflow was **fast**, but it has a cost: you can lose details if you don't stop and write things down.
@ -47,7 +47,7 @@ Still, it was the right choice for this kind of project. I wanted results, not b
## Where the AI got lost (and where I had to step in)
Most problems were not on the backend side (there is no backend 😄).
Most problems were not on the backend side (there is no backend 😄).
The real issues were **UI** and **visual details**:
- moving layouts from Angular to Astro: spacing and alignment were often "almost right", but not correct
@ -66,7 +66,7 @@ That last 20% is where you spend most of the time, really... this 20% cost me re
The biggest pain wasn't the framework. It was **content**.
I had to rewrite pages and sections into **Markdown / MDX**, then make sure Astro renders them correctly (Astro has its own way, and content collections are powerful but different if you come from Angular).
I had to rewrite pages and sections into **Markdown / MDX**, then make sure Astro renders them correctly (Astro has its own way and content collections are powerful but different if you come from Angular).
In the end it's worth it: now writing a post is literally creating a `.md` file and pushing it.
@ -102,11 +102,11 @@ And if the site is light, you also reduce bandwidth and compute. Not saving the
One reason I went with a static setup (S3 + CloudFront) is cost predictability.
For a personal site, storage on S3 is usually negligible (were talking cents/month for a few hundred MB).
For a personal site, storage on S3 is usually negligible (were talking cents/month for a few hundred MB).
CloudFront also has a generous "always free" tier (1 TB data transfer out + 10M HTTP(S) requests per month), which is more than enough for a normal personal blog.
The only “fixed” recurring cost I really consider is DNS: Route 53 hosted zone is $0.50/month (plus the domain).
And cache invalidations are free for the first 1,000 paths/month, so regular deploys dont cost anything.
The only “fixed” recurring cost I really consider is DNS: Route 53 hosted zone is $0.50/month (plus the domain).
And cache invalidations are free for the first 1,000 paths/month, so regular deploys dont cost anything.
## Performance and the "four green gauges" obsession
@ -117,8 +117,8 @@ At some point I started chasing Lighthouse scores like a videogame.
<em class="text-sm block mt-2">Lighthouse scores for lorenzoiovino.com</em>
</div>
Accessibility was the most fun one. Lighthouse kept telling me: **bad contrast**.
So I had to choose better colors, especially for text and dark mode.
Accessibility was the most fun one. Lighthouse kept telling me: **bad contrast**.
So I had to choose better colors, especially for text and dark mode.
It's a small thing, but it makes the site nicer to read. And it's also just… the right thing to do.
Then there was performance, especially around:
@ -132,22 +132,22 @@ Then there was performance, especially around:
Two things that helped a lot:
- make Google Fonts non-blocking (`font-display: swap`) and avoid [FOIT](https://fonts.google.com/knowledge/glossary/foit)
- give priority to the hero image ([LCP](https://web.dev/articles/lcp)), and don't lazy load above-the-fold content
- give priority to the hero image ([LCP](https://web.dev/articles/lcp)) and don't lazy load above-the-fold content
This kind of change is boring, but the result is visible (and Lighthouse stops yelling).
### Image optimization: the "Astro saved me" moment
In the old site, images were not optimized. Some were huge.
In the old site, images were not optimized. Some were huge.
My first thought was: "ok, I know this… I can build an AWS Lambda that resizes and optimizes images on the fly, then put CloudFront in front".
I did similar things at work.
But… for my personal site it was too much.
But… for my personal site it was too much.
More moving parts, more cost, more complexity.
Then I discovered something very nice: **Astro can optimize images at build time** (Astro Assets).
So I moved images into the project assets, used the `<Image />` component, and let the build do the job.
Then I discovered something very nice: **Astro can optimize images at build time** (Astro Assets).
So I moved images into the project assets, used the `<Image />` component and let the build do the job.
Result: smaller images, automatic formats (like [WebP](https://developers.google.com/speed/webp)), no extra infrastructure.
@ -157,12 +157,12 @@ That was a big win: less complexity, better performance, cheaper hosting.
Lighthouse is great, but I also used tools like [**Screaming Frog**](https://www.screamingfrog.co.uk/seo-spider/) to see issues in a more "SEO crawler" way (missing meta, duplicated titles, broken stuff, etc.).
It's a different view of the site, and sometimes it highlights problems you don't notice when you just browse your own pages.
It's a different view of the site and sometimes it highlights problems you don't notice when you just browse your own pages.
## What I learned (and what I would do again)
- Astro is a great fit for content sites
- static hosting is boring, and boring is good
- static hosting is boring and boring is good
- AI can speed up the migration a lot, but you still need to review and fix the last details
- performance work is not "one big thing", it's a lot of small fixes
- accessibility is not optional -> it makes your site better