Astro (TypeScript)
1/23/2025
Comprehensive guidelines for developing and maintaining an Astro project using TypeScript and TailwindCSS.
# Astro TypeScript Project Rules and Implementation Guide
This rule set is designed for production Astro projects that use TypeScript and Tailwind CSS. It gives Cursor enough project context to generate components that match Astro's server-first model instead of treating every page like a client-rendered React application. Use the guide as both a ready-to-copy rule and a checklist for reviewing AI-generated changes.
## When to use this rule
Use it for documentation sites, marketing pages, content-heavy products, portfolios, and other projects where static HTML and low client-side JavaScript are priorities. It is also suitable for Astro projects that selectively use React, Vue, Svelte, or another UI framework through islands.
Before adding the rule, confirm the project's Astro version, package manager, enabled integrations, content source, deployment adapter, and styling conventions. Update version-specific instructions when the project upgrades.
## Recommended project structure
Keep page routing, reusable UI, layouts, data, and public assets clearly separated:
- `src/pages/` contains route entry points and API endpoints.
- `src/layouts/` contains shared document shells and metadata behavior.
- `src/components/` contains small, focused Astro or framework components.
- `src/content/` contains validated content collections.
- `src/lib/` contains pure utilities, data access, and shared types.
- `public/` contains assets that do not require build-time processing.
Prefer feature-oriented subdirectories when a component, schema, and utility belong to the same capability. Do not create a general `utils.ts` dumping ground. Each module should have one clear responsibility and a name that describes its domain.
## TypeScript and data rules
Enable Astro's strict TypeScript preset. Avoid `any`; use `unknown` at external boundaries and narrow it with validation or type guards. Define component props explicitly and destructure them from `Astro.props`. Treat URL parameters, form values, environment variables, CMS responses, and JSON files as untrusted input.
Use Astro content collections with schemas for editorial content. A schema should validate required titles, descriptions, publication dates, tags, and draft status. Normalize data once near the source rather than repeatedly inside presentation components. When a value may be absent, model that state in the type and render an intentional fallback.
## Astro component rules
Render static content on the server by default. Add a client directive only when a component needs browser state, event handlers, or browser-only APIs. Choose the least expensive directive that meets the requirement: `client:visible` for below-the-fold interactions, `client:idle` for nonessential widgets, and `client:load` only for immediately interactive controls.
Keep frontmatter focused on data loading and preparation. Keep markup semantic and readable. Extract a component when it is reused, independently testable, or large enough to hide the page's structure. Do not convert a static Astro component into a hydrated framework component merely for code-style consistency.
## Styling and accessibility
Use Tailwind utilities consistently with the project's design tokens. Avoid arbitrary colors and spacing when an existing token communicates the same intent. Extract repeated visual patterns into components or documented class helpers; do not hide one-off markup behind unnecessary abstractions.
Every page must have one descriptive `h1`, a logical heading hierarchy, keyboard-accessible controls, visible focus states, meaningful link text, and labels for form inputs. Images need accurate `alt` text unless they are decorative. Interactive elements must remain usable without relying on color alone. Respect reduced-motion preferences and test layouts at narrow mobile widths.
## Performance and island boundaries
Astro's advantage is shipping little JavaScript, so every hydration directive requires justification. Keep large libraries out of the client bundle when the same work can happen during build or on the server. Use Astro's image tooling for local images, specify dimensions to prevent layout shift, and lazy-load noncritical media.
Avoid fetching the same data in multiple components. Load shared page data once and pass the smallest required shape through props. Prefer static generation for stable content and use server rendering only when freshness, authentication, or per-request behavior requires it.
## SEO and content metadata
Give every indexable page a unique title, description, canonical URL, and social preview. Do not repeat the site name multiple times in a title. Use descriptive URLs and ensure internal links lead to useful, complete pages. Generate a sitemap for public content and exclude test routes, previews, account screens, and thin utility pages.
For structured data, only describe content visible on the page. Dates, author information, breadcrumbs, and article metadata must match the rendered content. Never invent ratings, reviews, or performance claims.
## Security and privacy
Never expose secrets through `PUBLIC_` environment variables. Validate and sanitize user input in API routes and server actions. Allowlist redirect destinations, set appropriate security headers, and avoid rendering untrusted HTML. If Markdown or CMS content can be submitted by users, sanitize it before output and moderate it before publication.
Load analytics and advertising only under the site's documented consent and privacy model. Do not place ads on error pages, test pages, empty search results, or other low-value screens. Never send email addresses, telephone numbers, or other directly identifying data in analytics events, URLs, or ad requests.
## Testing checklist
Test pure utilities and schema transformations with unit tests. Add integration tests for content loading, dynamic routes, and API behavior. Use browser tests for navigation, forms, responsive menus, theme changes, and other critical user journeys.
Before merging a change, run type checking, linting, unit tests, and a production build. Inspect generated pages without JavaScript where practical, check for broken internal links, and verify that there are no unexpected hydration warnings. Test at least one representative page on a small mobile viewport and with keyboard navigation.
## Deployment safeguards
Match the adapter to the hosting platform and document why server rendering is required if it is enabled. Keep environment-specific settings outside source code, validate required environment variables during the build, and fail clearly when configuration is missing. Use preview deployments for content and routing changes.
Confirm that canonical URLs use the production domain, redirects do not form chains, the sitemap contains only canonical indexable URLs, and `robots.txt` does not block required assets. After deployment, monitor 404s, server errors, Core Web Vitals, and build warnings.
## Ready-to-use Cursor rule
Copy the following principles into a project-level `.cursor/rules/astro-typescript.mdc` file and add repository-specific commands and paths:
```md
---
description: Production rules for Astro, strict TypeScript, and Tailwind CSS
globs: ["src/**/*.{astro,ts,tsx}", "astro.config.*"]
alwaysApply: true
---
- Preserve Astro's server-first architecture and ship no client JavaScript by default.
- Add a client directive only for genuine browser interaction, using the least eager directive.
- Use strict TypeScript, explicit props, and validated data at external boundaries.
- Keep routes, layouts, components, content, and domain utilities clearly separated.
- Use semantic HTML, keyboard-accessible controls, visible focus states, and useful alt text.
- Reuse documented Tailwind tokens and avoid arbitrary styling when a token exists.
- Provide unique metadata and canonical URLs for every indexable page.
- Do not expose secrets through PUBLIC_ variables or render unsanitized external HTML.
- Do not place ads or analytics identifiers on test, error, empty, or low-value pages.
- Run type checks, tests, linting, and a production build before proposing completion.
```
## Common mistakes to reject
Reject generated changes that hydrate an entire page for one button, use `any` for convenience, duplicate metadata across routes, fetch data repeatedly, expose server secrets to the browser, or add placeholder links. Also reject instructions that refer to nonexistent commands or APIs without adding the required dependency and documentation.
A useful Cursor rule should reflect the actual repository. Review this file whenever Astro, TypeScript, Tailwind, the deployment adapter, or the content model changes. Keeping the rule specific and current is more valuable than adding a long list of generic coding preferences.