This blog started out as the project from Astro’s official tutorial. These are my notes from that first stretch: what I built, why I picked Astro, and what tripped me up along the way.
What I built first
- Installing Astro: First, I created a new Astro project and set up my online accounts.
- Making Pages: I then learned how to make pages by creating new
.astrofiles and placing them in thesrc/pages/folder. - Making Blog Posts: I wrote my first posts as Markdown files, which Astro turns into pages. This post started out as one of them.
It was honestly a little surreal to see a page I built myself show up in a real browser. A few weeks earlier I couldn’t have told you the difference between a static site and a server-rendered one, and by the end of the tutorial I had navigation, a footer, and even a dark mode toggle. Small wins, but they add up fast.

Why I picked Astro
I looked at a few frameworks before landing here. What sold me was the “islands” idea — most of the page ships as plain HTML, and only the bits that actually need JavaScript (like a button that changes state) get hydrated in the browser. Everything else stays server-rendered and fast.
If you can write HTML, you can write Astro components!
That line from Why Astro? is roughly how I’d explain it to my past self.
A quick taste of what a component’s frontmatter looks like:
---
const pageTitle = "About Me";
const skills = ["HTML", "CSS", "JavaScript"];
---
<h1>{pageTitle}</h1>
<ul>
{skills.map(skill => (
<li>{skill}</li>
))}
</ul>
That’s it — a fenced code block at the top for logic, then plain HTML-ish markup below it. No separate templating language to learn, no build step surprises.
Things that tripped me up
Nothing was too painful, but a few things took a second read of the docs:
- Scoped styles don’t cross component boundaries. A
<style>block only affects elements that live in that exact component’s own template — not elements a parent layout renders around your slotted content. I hit this directly: a heading color rule I wrote on my first post page silently did nothing once the heading moved into a shared layout. - Dates need a timezone. Formatting a
DatewithtoLocaleDateString()uses whatever timezone the machine building the site happens to be in. A post dated July 1st can print as June 30th depending on where it’s built, unless you pin the timezone explicitly. - File-based routing is stricter than it looks.
src/pages/tags/[tag].astroversussrc/pages/tags/index.astroare two very different files with very different jobs, and it’s easy to reach for the wrong one at first.

Where it went next
Since finishing the tutorial, I’ve moved this site onto the AstroPaper theme and added support for writing posts in AsciiDoc, which I cover in Writing Blog Posts in AsciiDoc.
If you’re following along and building your own site, my one piece of advice is: don’t skip the “why” sections in the docs. It’s tempting to just copy-paste the code blocks, but the parts explaining why Astro made a particular choice are what made the rest of it click for me.