Blueprint
Astro 7 Starter Theme: Production-Ready Blueprint (Tailwind 4 + Full SEO)
TL;DR: Open the blueprint on GitHub, follow the steps, and you have my Northbeam corporate theme running. Astro 7.0.2 and Tailwind CSS 4.3, with oklch design tokens, the full SEO stack (canonical URLs, Open Graph, Twitter cards, JSON-LD), RSS, an auto-generated sitemap, and a custom 404 page. No "why is Tailwind not working" detour on the way there.
Search for an Astro tutorial today and the odds are good you’ll land on one written for Astro 5. It will look current. It will mostly work. Then one install command will quietly do the wrong thing, and you’ll spend an afternoon finding out why.
That gap between versions 5 and 7 is why I started writing blueprints. Astro is the best JavaScript framework going right now, and the fastest growing, which is exactly the problem — the documentation around it ages faster than the framework does. This is the second in the series. The Astro 6 starter theme covered the fundamentals; this one adds full JSON-LD to the SEO stack, a custom 404 page, and a corporate design that doesn’t read as stock Tailwind.
What’s actually in my Astro 7 stack
No mystery dependencies
Every layer earns its place. Astro 7 ships zero JavaScript by default, so you render HTML and CSS and add interactivity only where something actually needs it. Styling is Tailwind CSS 4 through the Vite plugin — that detail matters, and it’s the next section. Content is native Astro and MDX. SEO is one <Seo /> component emitting canonical URLs, Open Graph, Twitter cards, and JSON-LD. The sitemap and the RSS feed generate themselves. Typography comes from the Tailwind plugin. And Node 22.12 is the floor, because Astro 6 dropped 18 and 20.
The one mistake that breaks every Astro 7 + Tailwind 4 setup
Read this before you install anything
Here’s the one that sends everybody to Google: Tailwind 4 is not an Astro integration anymore. Any tutorial telling you to run npm install @astrojs/tailwind was written for Tailwind 3. On a v4 project that package either throws errors or, worse, misbehaves quietly — and quiet is expensive, because you’ll debug your CSS for an hour before it occurs to you that the install was wrong.
On Astro 7, npx astro add tailwind installs tailwindcss plus @tailwindcss/vite and registers the plugin under vite.plugins, never under integrations. There is no tailwind.config.js either. Tailwind 4 is CSS-first, so the whole design system lives in an @theme { … } block inside global.css. Learn the diagram below and you skip the most common Astro 7 failure entirely.
A clean modern corporate design done right
oklch palette, one @theme block
Lean on the out-of-the-box gray-* and blue-* and your site looks like every other Tailwind site. Your eye clocks it in about a second, even if you couldn’t say why. So the blueprint defines its own palette in @theme using oklch, which keeps lightness perceptually even across hues — your hover states and your dark bands stop drifting against each other. There’s an ink-* ramp for text, a teal brand-* accent, a warm signal-* for calls to action, and named surface and line tokens.
Tailwind then generates real utilities from those names: text-ink-700, bg-brand-500, border-line. Use those instead of the defaults and the site stops reading as “a Tailwind project” and starts reading as yours.
The full SEO package: Canonicalization, OG, Twitter, and JSON-LD
One component, every page
This is the part that earns the “production-ready” label. One <Seo /> component resolves the canonical URL against your configured site, builds an absolute Open Graph image URL (social scrapers reject relative paths, and they reject them silently), emits the Twitter card tags, and outputs a schema.org @graph. That graph defines your Organization once and references it by @id from a per-page node — WebPage for pages, BlogPosting for articles. Google sees one connected entity instead of three disconnected blobs.
The trap that gets everyone: JSON-LD has to be emitted with
set:html={JSON.stringify(data)}. Drop a raw object between the script tags and Astro escapes your quotes into", which is invalid JSON, which crawlers discard without a word of complaint.
@graph wins: one source of truth for your brand entity, reused by every page type.The gotchas that cost the most time
Learned the expensive way
Sixteen gotchas are documented in the blueprint. These five are the ones that cost me the most time:
- Set
sitein astro.config.mjs — non-negotiable.Canonical URLs, the sitemap, and RSS links all derive from it. Leave it out and your canonicals resolve to
undefinedwhile the sitemap skips itself without saying so. - The Rust compiler enforces valid HTML nesting.
The old Go compiler quietly fixed bad markup. Rust doesn't. A
<div>inside a<p>closes the paragraph early and takes your layout with it. Audit the MDX wrappers. - A
backdrop-blurheader breaks afixedmobile menu.Any ancestor with
filter,backdrop-filter, ortransformbecomes the containing block for fixed children — that's the "transparent menu" bug. Render the overlay as a sibling of the header, not a child. - Pick one trailing-slash policy and mirror it everywhere.
RSS adds a trailing slash by default regardless of config, so set
trailingSlash: falsein therss()call or your feed links won't match your real URLs. - Your custom 404 must return a 404, not a 200.
Managed hosts handle this. A naive static server will happily serve a "soft 404" with status 200, and Google will happily index it. Check with
curl -Iagainst the host you actually deploy to.
Copy. Paste. Ship.
Grab the Astro 7 starter theme blueprint
The complete blueprint — every config file, component, sample post, and all sixteen gotchas — is free on GitHub. No newsletter wall, no "premium tier."
If this saved you an afternoon, that was the whole point. Go build something. If I’ve missed something, post it to the repo and I’ll fold it in — and there’ll be another blueprint when the next Astro version lands. The Astro 7 starter theme is here; the Astro 6 version is still there if you’re not ready for the jump.
// Let's talk
You have ideas.
I have IT solutions.
Fifteen minutes on Zoom is usually enough to tell whether I'm the right person for what you're building.
Denver, CO · Available for architecture, infrastructure, and DevOps engagements