A lean, production-ready Astro v6 monorepo template with Tailwind v4, Svelte 5 and Biome.
Status: Astro v6 is stable. This template tracks the latest Astro v6 releases.
This template uses pnpm workspaces with a shared library, making it an ideal foundation for running multiple projects from a single repository. Typical use cases:
- Main site + Blog (included as
starterandblog) - Landing pages for campaigns or product launches
- Online shop storefront
- Documentation site
All projects share the same design tokens, UI components and utilities — ensuring a consistent look and feel while keeping each app independently deployable. Adding a new project is as simple as creating a new folder under apps/ and importing from shared/.
This template succeeds astro-v5-template. It was rebuilt from scratch with a focus on simplicity and the Astro v6 feature set.
| Area | v5 | v6 |
|---|---|---|
| Apps | 3 (blank, base, demo) | 2 (starter, blog) |
| Linting | Biome + ESLint + Prettier | Biome only |
| Fonts | 16 packages | 3 (Inter, Lora, Fira Code) |
| Styling | @casoon/atlas + Tailwind | Custom tokens + Tailwind v4 |
| Node | >= 20 | >= 22.12.0 |
| Zod | v3 | v4 |
| Content | Legacy Collections | Loader API |
| Dev server | Standard Vite | Vite Environment API |
- Astro v6 — New dev server, Live Content Collections, CSP, Sessions
- Tailwind v4 — CSS-first config, Vite plugin, OKLCH colors
- Svelte 5 — Runes API ($state, $derived) for reactive islands
- i18n — Multi-language support (en/de) with Astro i18n routing
- OG Images — Auto-generated Open Graph images at build time (Satori + resvg)
- Astro Actions — Server-side form handling (contact, newsletter, feedback)
- CSP — Content Security Policy with SHA-256 nonces
- Sessions — Server-side session management via Cloudflare KV
- Build Metrics —
@casoon/astro-speed-measurefor build performance tracking - Post-Build Audit —
@casoon/astro-post-auditfor SEO, link and WCAG checks after every build - Secret Scanning —
@casoon/nosecretsin pre-commit plus manual workspace scans - Playwright — E2E tests for both apps with axe-core a11y scanning
- Biome — Single tool for linting + formatting (replaces ESLint + Prettier)
- Zod v4 — Runtime validation for env, forms, API
- pnpm Workspaces — Monorepo with catalog for centralized dependency management
- Dark Mode — System preference + manual toggle
- Sitemap —
@casoon/astro-sitemapgenerates/sitemap.xmlat build time with i18n hreflang, RSS feed, and pattern-based priority/changefreq rules - Crawler Policy —
@casoon/astro-crawler-policygeneratesrobots.txtandllms.txtfrom a curated bot registry with presets for SEO, AI training control and citation-friendliness - SEO — robots.txt, canonical URLs, meta descriptions, JSON-LD
- WCAG 2.1 AA — Two-layer accessibility: axe-core runtime checks + static HTML audit
- TypeScript Strict — Fully typed throughout
Tip: For additional ready-made Tailwind v4 components (buttons, cards, modals, navigation and more), check out webspire.de — a component library built on Tailwind v4 that pairs well with this template.
astro-v6-template/
├── apps/
│ ├── starter/ # Landing page + contact form + i18n
│ └── blog/ # Blog with MDX + RSS + i18n
├── shared/ # Design tokens, components, layouts, SEO, utilities
├── e2e/
│ ├── starter/ # Playwright E2E tests for starter
│ └── blog/ # Playwright E2E tests for blog
├── .github/workflows/ # CI pipeline
├── biome.json # Linting & formatting
├── playwright.config.ts # E2E test configuration
└── pnpm-workspace.yaml # Workspace + catalog
- Node.js >= 22.12.0
- pnpm >= 9.0.0
# Clone the repository
git clone https://github.com/casoon/astro-v6-template.git
cd astro-v6-template
# Install dependencies
pnpm install
# Start the starter app
pnpm dev
# Start the blog app
pnpm dev:blog| Script | Description |
|---|---|
pnpm dev |
Start the starter app (port 4321) |
pnpm dev:blog |
Start the blog app (port 4322) |
pnpm build |
Build all apps |
pnpm build:starter |
Build starter only |
pnpm build:blog |
Build blog only |
pnpm check |
Run Biome lint + format check |
pnpm check:fix |
Biome auto-fix |
pnpm format |
Format all files |
pnpm test:e2e |
Run all Playwright E2E tests |
pnpm test:e2e:starter |
E2E tests for starter only |
pnpm test:e2e:blog |
E2E tests for blog only |
pnpm type-check |
TypeScript check |
pnpm clean |
Remove build artifacts + node_modules |
Landing page featuring:
- Hero section with feature grid
- Contact form with Astro Actions + Zod validation
- Newsletter subscription and feedback actions
- API route (
/api/contact) - i18n (English + German) with language switcher
- OG image generation per page and locale
- Dark mode toggle
- SEO component with JSON-LD
Blog template featuring:
- MDX support
- Content Collections (Loader API)
- Automatic RSS feed (
/rss.xml) viaastroSitemapintegration - Automatic sitemap (
/sitemap.xml) with i18n hreflang - i18n (English + German) with language switcher
- OG image generation per page and blog post
- Tag display
- Responsive post layout
All shared code lives in shared/:
- Styles — Design tokens (OKLCH), global CSS, Tailwind theme
- Components —
Navbar.astro,ThemeToggle.svelte - Layouts —
BaseLayout.astro(HTML base with skip link) - SEO —
PageSEO.astro(meta tags, Open Graph, JSON-LD) - Utilities —
env.ts,api.ts,cn.ts,i18n.ts,og.ts
Both apps support English (default) and German:
- English pages at root:
/,/contact,/blog/welcome - German pages with prefix:
/de/,/de/contact - Language switcher in the navbar (EN/DE links)
- Translation files per app in
src/i18n/ - Shared locale utilities in
@astro-v6/shared/utils/i18n
Open Graph images are generated at build time:
# Generate manually
pnpm --filter starter generate:og
pnpm --filter blog generate:og
# Runs automatically before `astro build`
pnpm build- Output:
public/og/*.png(1200x630, gitignored) - Blog script reads MDX frontmatter to generate post-specific images
- All pages reference their OG image via
<PageSEO ogImage={...}>
# Run all tests (builds must exist)
pnpm test:e2e
# Run per app
pnpm test:e2e:starter
pnpm test:e2e:blogTests covering navigation, i18n, SEO/OG meta tags, contact form, theme toggle, RSS, accessibility (axe-core WCAG 2.1 AA), robots.txt and sitemap.
# Scan the whole workspace
pnpm secrets:scan
# Scan only staged files (used by pre-commit)
pnpm secrets:scan:stagedBoth apps include @casoon/astro-speed-measure to track build performance. It measures integration hooks, Vite plugin timing, per-page rendering and asset processing — giving you visibility into what slows down your build.
// astro.config.mjs
import speedMeasure from '@casoon/astro-speed-measure';
export default defineConfig({
integrations: [
// ... other integrations
speedMeasure(), // always add as last integration
],
});Each build prints a performance report to the console and writes a JSON baseline for trend comparisons. Supports budgets, HTML reports and GitHub Actions CI summaries.
Both apps include @casoon/astro-post-audit for automatic SEO, link and WCAG checks after every build. It runs a fast Rust binary against the build output via the astro:build:done hook.
The template ships with comprehensive rules enabled out of the box:
// astro.config.mjs
postAudit({
throwOnError: false,
rules: {
filters: { exclude: ['404.html'] },
canonical: { self_reference: true },
headings: { no_skip: true },
html_basics: { meta_description_required: true },
opengraph: {
require_og_title: true,
require_og_description: true,
require_og_image: true,
},
a11y: {
require_skip_link: true,
require_img_alt: true,
require_button_text: true,
require_label: true,
},
links: { check_fragments: true },
sitemap: {
require: true,
canonical_must_be_in_sitemap: true,
entries_must_exist_in_dist: true,
},
security: { check_target_blank: true },
hreflang: {
check_hreflang: true,
require_x_default: true,
require_self_reference: true,
require_reciprocal: true,
},
},
}),Checks include canonical URLs, meta descriptions, Open Graph tags, heading hierarchy, broken links with fragment validation, sitemap cross-referencing, target="_blank" security, hreflang reciprocal validation and WCAG heuristics (skip link, alt text, button text, form labels). Set throwOnError: true for strict CI enforcement.
Both apps use @casoon/astro-sitemap to generate /sitemap.xml as part of astro:build:done — no extra page route needed.
// astro.config.mjs
import astroSitemap from '@casoon/astro-sitemap';
import { getBlogRssItems } from './src/utils/blog-rss.js';
astroSitemap({
i18n: {
defaultLocale: 'en',
locales: { en: 'en', de: 'de' }, // adds xhtml:link hreflang entries
},
priority: [
{ pattern: '/blog/', priority: 0.7 },
],
changefreq: [
{ pattern: '/blog/', changefreq: 'monthly' },
],
rss: {
title: 'Astro v6 Blog',
description: 'A blog template built with Astro v6, MDX and Content Collections.',
language: 'en',
getItems: getBlogRssItems, // reads MDX frontmatter via gray-matter
},
}),The getItems helper (src/utils/blog-rss.js) reads MDX frontmatter directly with gray-matter rather than getCollection(), because Astro's content API is unavailable inside the build hook.
Features: static page discovery from Astro's build output, i18n hreflang links, RSS feed generation, pattern-based priority/changefreq, sitemap-index chunking for large sites (>50k URLs).
Both apps use @casoon/astro-crawler-policy to generate robots.txt (and optionally llms.txt) from a curated bot registry.
// astro.config.mjs
import crawlerPolicy from '@casoon/astro-crawler-policy';
crawlerPolicy({
sitemaps: ['https://astrov6blog.casoon.dev/sitemap.xml'],
// preset: 'seoOnly' | 'citationFriendly' | 'openToAi' | 'blockTraining' | 'lockdown'
}),The default preset (seoOnly) allows all verified search engine bots and blocks AI training crawlers. Override per environment via the env option.
This template enforces WCAG 2.1 Level AA compliance through two complementary layers:
@casoon/astro-post-audit runs automatically after every build and checks the raw HTML output for:
- Missing
altattributes on images - Empty links (
<a>without text or aria-label) - Missing page landmarks and heading structure
- Duplicate
<h1>elements per page
axe-core via @axe-core/playwright validates the fully rendered pages in a real browser:
- Color contrast ratios (>= 4.5:1)
- ARIA roles and attributes
- Keyboard navigation and focus management
- Form label associations
# Run accessibility tests
pnpm test:e2e # all tests including a11yTests are located in e2e/starter/a11y.spec.ts and e2e/blog/a11y.spec.ts.
- Skip to content link in
BaseLayout - Semantic HTML —
<nav>,<main>,<article>,<section>throughout - ARIA attributes —
aria-label,aria-current,rolewhere needed - Link underlines — Always visible, not just on hover
- Focus indicators — Visible focus rings on all interactive elements
- Dark mode — Respects
prefers-color-scheme, OKLCH colors maintain contrast in both modes
This template leverages the key features of Astro v6:
- Vite Environment API — Dev server runs in the same runtime as production
- Content Collections Loader API —
glob()loader instead of legacytype: 'content' - Content Security Policy — Built-in CSP with SHA-256 nonces
- Sessions — Server-side session management (Cloudflare KV)
- Astro Actions — Type-safe server-side form handling
- Zod v4 —
z.email(),z.url()as top-level functions - Node 22+ — Minimum requirement
This template includes a Claude Code setup for AI-assisted development:
- MCP Servers (
.claude/mcp.json) — Pre-configured MCP servers for context7 documentation lookup, Cloudflare tooling, and Webspire UI patterns - Project instructions (
CLAUDE.md) — Architecture rules, code conventions, and dependency constraints
For the full set of reusable Claude Code skills (Astro, Tailwind, Svelte, SEO, Playwright, and more), see casoon/ai-agent-config.
MIT