⭕️ AstroWind: A free template using Astro v7 and Tailwind CSS v4. Astro starter theme.
# AstroWind Agent Instructions
## Project Overview
AstroWind is a free, open-source website template built with **Astro v7** and **Tailwind CSS v4**. It generates a fully static site optimized for performance, SEO, and accessibility.
**Stack:** Astro v7 | Tailwind CSS v4 | TypeScript 5.9 | MDX | Sharp
## Quick Reference
| Command | Purpose |
| ----------------- | ----------------------------------- |
| `npm run dev` | Start dev server at localhost:4321 |
| `npm run build` | Production build to `./dist/` |
| `npm run preview` | Preview production build locally |
| `npm run check` | Run astro check + ESLint + Prettier |
| `npm run fix` | Auto-fix ESLint + Prettier issues |
**Node.js requirement:** >= 22.12.0
## Architecture
### Directory Structure
```
src/
assets/styles/tailwind.css # Tailwind v4 config (themes, utilities, plugins)
components/
common/ # Shared: Image, Metadata, Analytics, ToggleTheme
ui/ # Primitives: Button, Form, Headline, Timeline, WidgetWrapper
widgets/ # Page sections: Hero, Features, Pricing, Header, Footer
blog/ # Blog: SinglePost, List, Pagination, Tags
CustomStyles.astro # CSS variables for colors and fonts
content.config.ts # Content Collections schema (Astro 5+ location)
data/post/ # Blog posts (.md, .mdx)
layouts/ # Layout.astro, PageLayout.astro, MarkdownLayout.astro
pages/ # File-based routing
utils/ # blog.ts, images.ts, permalinks.ts, frontmatter.ts
config.yaml # Site configuration (loaded as virtual module)
navigation.ts # Navigation structure
types.d.ts # TypeScript type definitions
vendor/integration/ # Custom Astro integration for config loading
```
### Path Aliases
Use `~/` to import from `src/`:
```typescript
import Image from '~/components/common/Image.astro';
import { SITE } from 'astrowind:config';
```
### Configuration System
Site config lives in `src/config.yaml` and is loaded as a Vite virtual module `astrowind:config` by the custom integration in `vendor/integration/`. Exports: `SITE`, `I18N`, `METADATA`, `APP_BLOG`, `UI`, `ANALYTICS`.
## Tailwind CSS v4
Configuration is CSS-first in `src/assets/styles/tailwind.css`:
- **Theme tokens:** `@theme { --color-primary: var(--aw-color-primary); ... }`
- **Custom utilities:** `@utility bg-page { ... }`
- **Dark mode:** Class-based via `@variant dark (&:where(.dark, .dark *))`
- **Plugins:** `@plugin "@tailwindcss/typography"`
- **Custom variant:** `@custom-variant intersect (&:not([no-intersect]))`
CSS variables for colors/fonts are defined in `src/components/CustomStyles.astro` with light/dark theme variants.
The Vite plugin `@tailwindcss/vite` is configured in `astro.config.ts` (not as an Astro integration).
### Class Merging
Components use `twMerge` from `tailwind-merge` v3 for conditional class composition.
## Content Collections
Defined in `src/content.config.ts` using Astro's Content Layer API with `glob()` loader. Posts are in `src/data/post/` as `.md` or `.mdx` files.
Post frontmatter: `title` (required), `publishDate`, `updateDate`, `draft`, `excerpt`, `image`, `category`, `tags`, `author`, `metadata`.
## Component Patterns
- Props extend interfaces from `~/types`
- Use `class:list` for conditional classes
- Use `twMerge()` when accepting className overrides
- Use named slots for layout composition
- Widget components accept standardized props (see `~/types`)
## Image Handling
`src/components/common/Image.astro` supports:
- Local images via `astro:assets` (optimized by Sharp)
- Remote images via Unpic CDN
- Allowed domains (for providers Unpic can't detect, processed by Sharp): `cdn.pixabay.com`
Hero images use `loading="eager"` and `fetchpriority="high"`.
## Fonts
Fonts are handled by Astro's native **Fonts API**, configured in `astro.config.ts` under the `fonts` key (provider, family, `cssVariable`) and injected via the `<Font />` component in `src/layouts/Layout.astro`. Astro self-hosts, subsets, preloads, and generates metric-adjusted fallbacks. To change the typeface, edit the `fonts` entry and point `--aw-font-*` in `CustomStyles.astro` at the new `cssVariable`.
## Third-party Scripts (Partytown)
`@astrojs/partytown` is wired as an **opt-in** in `astro.config.ts`, gated behind `const hasExternalScripts = false`. Set it to `true` to offload third-party scripts (e.g. Google Analytics via `analytics.vendors.googleAnalytics.partytown`) to a web worker. It is disabled by default so the base template ships no external scripts.
## Content Security Policy
Astro's native CSP is intentionally **not** enabled in this version: it is incompatible with `<ClientRouter />` view transitions (shipped on by default) and would break the arbitrary third-party scripts a template user typically adds. CSP is deferred to AstroWind v2, where the component model (and optional SSR) make it clean and opt-in.
## Verification Checklist
After changes, always verify:
1. `npm run build` succeeds
2. `npm run check` passes (astro check + ESLint + Prettier)
3. Visual check in browser: homepage, blog, dark mode, mobile menu