← All Templates

Astro Website with Playwright

Rules for building Astro websites with Playwright E2E testing, optimized for token-efficient LLM usage.

typescript javascript web playwright vitest astro

v1.0.0 · Updated Apr 9, 2026

CLAUDE.md — Save as CLAUDE.md in your project root.

Project Setup

Suggest Change
- Scaffold with `npm create astro@latest` using the minimal template
- Use hybrid output mode in `astro.config.mjs` for SSG pages with SSR API routes
- Install only required integrations; avoid unnecessary dependencies
- Use Edit tool for config changes; never overwrite entire config files
- Run npm run dev to verify setup before writing any components
- Structure: `src/pages/` for routes, `src/components/` for UI, `src/content/` for data
- Use TypeScript strict mode; define prop interfaces on every component

Testing Strategy

Suggest Change
- Follow RED-GREEN-REFACTOR: write the failing test first, implement minimally, then refactor
- Use Vitest for unit tests (`*.test.ts`), Playwright for E2E (`*.spec.ts`)
- Run unit tests with npm test after every implementation change
- Run E2E tests only after unit tests pass: `npx playwright test`
- Test file location mirrors source: `src/components/Button.astro` -> `tests/components/Button.test.ts`
- Keep test descriptions concise; prefer `test('renders title')` over verbose descriptions
- Mock external APIs in unit tests; use real endpoints in E2E only
- Avoid snapshot tests; prefer explicit assertions on visible text and attributes

Playwright Configuration

Suggest Change
- Configure `playwright.config.ts` with `webServer` pointing to `npm run preview`
- Set `testDir: './e2e'` to separate E2E from unit tests
- Use only Chromium for local dev; add Firefox/WebKit in CI only
- Prefer `page.getByRole()` and `page.getByTestId()` over CSS selectors
- Use `test.describe()` blocks for logical grouping
- Set `--reporter=list` for token-efficient output; avoid HTML reporter in CI
- Configure `expect.toHaveScreenshot()` only for visual regression tests, not as primary assertions
- Always `await` navigation: `await page.goto('/')` then `await page.waitForLoadState('networkidle')`
- Use `test.beforeEach` for common setup; avoid `test.beforeAll` unless truly shared state

Component Patterns

Suggest Change
- Prefer `.astro` components for static content; use Preact islands only for interactivity
- Add `client:load` for above-fold interactive components, `client:visible` for below-fold
- Keep island components small; pass data as serializable props from Astro
- Use Read tool before editing any component to understand its current structure
- CSS: use Tailwind utility classes; define custom theme tokens in `tailwind.config.mjs`
- Accessibility: every interactive element needs `aria-label` or visible label text
- Images: use Astro's `<Image>` component with explicit `width` and `height`
- Slots: use named slots for composable layouts (`<slot name="header" />`)

Deployment

Suggest Change
- Run npm run build and verify zero errors before deploying
- Use Bash to run `npx astro check` for TypeScript validation
- Static pages auto-prerender; add `export const prerender = false` only for SSR routes
- Set `Cache-Control` headers on API routes: `public, max-age=300` for cacheable data
- Environment variables: use `import.meta.env` for client-safe vars, `process.env` for server-only
- Never commit `.env` files; use `.env.example` as documentation