SEO Checklist for a Static Site: Sitemap, Hreflang, and Schema

After moving to Astro, I briefly forgot something important: a static site isn’t automatically SEO-friendly just because it’s fast. It took a few weeks after launch before I actually sat down and fixed this stuff properly — partly because I was procrastinating, partly because I only found the problems after checking Search Console and noticing some English-language pages weren’t indexed at all.
Sitemap — the part I barely think about anymore
@astrojs/sitemap generates sitemap-index.xml automatically at build time, based on the site defined in astro.config.mjs. Submit it once to Google Search Console, and after that I basically never think about it again — every new blog post automatically shows up in the sitemap the moment a deploy runs. Honestly the easiest item on this whole checklist.
Hreflang, the one that actually took me the longest to sort out
Since this site has an Indonesian version (/) and an English version (/en/...), I need to tell Google these are language variants of the same content, not duplicates. That’s done with <link rel="alternate" hreflang="..."> tags in the <head> of every page, pointing to the equivalent URL in the other locale, plus one x-default tag pointing at the default version (Indonesian, since prefixDefaultLocale: false).
This is the part that’s easiest to get wrong, and I did get it wrong. A few weeks after launch I checked Search Console and found several /en/blog/... pages flagged as “duplicate, Google chose different canonical” — turned out the hreflang tags on a handful of older posts pointed at the wrong slug, a leftover from before I’d locked down the ID/EN slug-matching convention. Took roughly half a day going through every pair to make sure the slugs actually lined up, then resubmitting through Search Console and waiting a few days for the status to clear.
Schema markup, whose payoff isn’t immediately visible
I added JSON-LD Person schema to the main layout — name, job title, location, skills. It’s not a direct ranking factor, and I don’t have hard evidence it’s moved traffic. But it costs basically nothing to include, and it helps Google (and increasingly, AI search like ChatGPT or Perplexity) understand who I am as an entity — useful if a knowledge panel or rich result ever shows up, and harmless if it never does.
robots.txt, which I nearly forgot
Simple, but easy to skip. It just allows every crawler and points to the sitemap location. It’s the first thing a crawler reads before touching the rest of the site, and I genuinely forgot to add it at first launch — only noticed two weeks later while checking server logs and realizing some crawlers were bouncing without fetching anything else afterward.
What I learned from all this: technical SEO for a static site is 80% getting metadata right and consistent, not tricks or growth hacks. Astro already does a lot of the heavy lifting on performance — this site’s Core Web Vitals are usually all green in PageSpeed Insights, thanks to minimal JavaScript by default. So the biggest remaining work is boring administrative stuff like the above, where missing one thing doesn’t show up until weeks later when you check Search Console and find pages that never got indexed, like I did.