Highlights
create-astro-fleet CLI (#8)
Scaffold a new fleet or add a site to an existing one without cloning the repo:
bunx create-astro-fleet # new fleet, interactive
bunx create-astro-fleet add acme.com saas # add a siteTwo subcommands (init + add), interactive prompts via @clack/prompts, giget-based template fetch, non-interactive flags (--domain, --preset, --template, --keep-demos). Cross-platform — replaces the bash-only new-site.sh for first-time users (the script stays for compatibility).
Keystatic CMS in the Meridian demo (#8)
Meridian now ships a working editable insights content collection with a Keystatic admin UI at /keystatic in dev. Content is Markdoc stored in git; production builds stay fully static. New docs/adding-a-cms.md covers the Meridian pattern, how to replicate it on any other site, the monorepo access-control caveat, and alternatives (Sanity, Directus, Decap, Payload, Tina) with guidance on when each is the right pick.
SEO hardening across the shared layer (#9)
packages/shared-ui/src/components/SEOHead.astro:
- Emits full robots directives (
max-snippet:-1, max-image-preview:large, max-video-preview:-1) on indexable pages - Suppresses canonical when
noindex=true og:imagenow includeswidth/height/alt; only emits when an image is actually provided (no more broken fallback)twitter:carddefaults tosummary_large_imagewhen an image is present- Drops meta keywords emission (prop retained with
@deprecated) - Declares
<link rel="icon" href="/favicon.svg"> - Auto-emits a linked
WebSite+OrganizationJSON-LD@graphfromsiteName,Astro.site,logoSrc, andsocialLinks(assameAs). User-suppliedstructuredDatamerges into the same graph so@idrefs resolve. Opt out per-page withskipAutoJsonLd. - New pass-through props on
BaseLayout:ogImageAlt,ogType,twitterHandle,noindex,rssUrl,skipAutoJsonLd
Site-level SEO infra (#9)
public/_headerson every site: 1-year immutable cache on/_astro/*(covers JS, CSS, and fonts under/_astro/fonts/);No-Vary-Searchon/to strip UTM + ad-click params from the CDN cache key- RSS feed for Meridian insights at
/rss.xml, advertised via<link rel="alternate" type="application/rss+xml"> - Insight detail pages emit
og:type=article
New docs
docs/adding-a-cms.md— Keystatic pattern + alternativesdocs/seo-recipes.md— optional P2 add-ons (per-page OG images with Satori+Sharp, git-based sitemap lastmod,llms.txt, markdown alternates, IndexNow, FuzzyRedirect, view transitions, schema endpoints, NLWeb, build-time validation)
CI fix
Removed duplicate .github/workflows/build.yml that was running in parallel with ci.yml without setting up Node 22. It always failed (Astro 6 requires Node ≥ 22.12) while ci.yml passed, producing the "fails first, works second" flakiness on every commit.
Breaking changes
None.
Deprecations
keywordsprop onBaseLayout/SEOHeadis accepted but no longer emitted as<meta name="keywords">— ignored by all major engines. Safe to remove from call sites at your leisure.
Upgrade notes
bun installpicks up the newcreate-astro-fleetpackage and Meridian's Keystatic deps.- Auto JSON-LD is on by default. Pages that emit a full custom
@graphcan opt out withskipAutoJsonLd. - Existing call sites passing
structuredDatacontinue to work — their nodes now merge into the auto-generated graph (with@contextstripped on merge to avoid duplication). _headersships per-site. First deploy after upgrade will serve the immutable cache headers; no action required on Cloudflare Pages.
What's Changed
- feat: create-astro-fleet CLI + Keystatic CMS example in Meridian (#8)
- feat: SEO hardening — P0 meta fixes, auto JSON-LD, _headers, RSS, recipes docs (#9)
Full Changelog: v2.1.0...v2.2.0