all posts
· 1 min read #astro#seo#engineering

Why I rebuilt the SouthForge site in Astro

The old site was a client-rendered React SPA, which quietly broke SEO and social sharing. Here's why I moved to Astro and what it fixed.

The old SouthForge site was a single-page React app. It looked fine, but it had a problem I couldn’t see from my own browser: every page’s <title>, meta description, and Open Graph tags were written by JavaScript after the page loaded.

Google can run JavaScript, so it mostly coped. But social scrapers — the bots behind X, LinkedIn, Discord, and iMessage link previews — don’t. They read the raw HTML response and stop. So every link I shared fell back to the generic homepage card, no matter which page it pointed at.

The fix: render real HTML

I moved the site to Astro. Astro renders components to static HTML at build time and only ships JavaScript for the few pieces that are actually interactive. That means:

  • Per-page titles, descriptions, and OG tags land in the initial HTML.
  • Structured data (JSON-LD) is in the source, not injected later.
  • Pages are faster, because there’s almost no client JS to parse.

What it unlocked

The real reason for the rebuild was this blog. A blog only earns SEO if each post is a real, crawlable, shareable page — its own title, its own social card, its own entry in the sitemap and RSS feed. That’s a natural fit for Astro’s content collections: a post is just an .mdx file with frontmatter, and everything else follows from it.

This post is the first one written on the new system.