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
- Custom Sitemap — Own
createSitemapRoute()utility generating/sitemap.xmlwith i18n and blog support (no@astrojs/sitemapneeded) - 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) - 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.
This template uses a custom createSitemapRoute() utility instead of @astrojs/sitemap. The official plugin generates a sitemap-index.xml, which search engines don't discover at the standard /sitemap.xml path. The custom route generates a proper /sitemap.xml directly.
// src/pages/sitemap.xml.ts
import { getCollection } from 'astro:content';
import { createSitemapRoute } from '@astro-v6/shared/utils/sitemap';
const pageModules = import.meta.glob('./**/*.astro', { eager: true });
export const GET = createSitemapRoute({
siteUrl: import.meta.env.SITE,
pageModules,
getBlogPosts: () => getCollection('blog'),
blogPrefix: '/blog',
locales: ['de'],
exclude: ['/blog/'], // exclude redirect-only pages
});Features:
- Scans
.astropage modules automatically (skips 404, API routes, dynamic routes) - Blog posts from Content Collections with per-post
<lastmod> - Localized URLs for all configured locales
- Configurable exclusion patterns
- Priority and changefreq based on page type (homepage > contact > blog posts)
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 full Claude Code setup for AI-assisted development:
- Skills (
.claude/skills/) — Domain-specific guidelines for Astro v6, Tailwind v4, Svelte 5, Playwright, Cloudflare, i18n, SEO, local business SEO, MDX, Biome, final-pass, and more - 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
MIT