Development Guidelines
These conventions apply to every Astro project created with the creation script. They are also enforced by the Cursor rules file (.cursor/rules/general.mdc) included in each project.
Content management
Rule: never hardcode text, links, or image URLs in components.
All content lives in src/data/front.yaml and is imported in each component:
This applies to:
- Headings and paragraphs
- Button labels
- Navigation links and
hrefattributes - Image
srcattributes and background images - Social media URLs
This makes it easy to update content later without touching component code.
Component structure
Page sections
- Each major page section should be its own
.astrocomponent insrc/components/. - Use semantic HTML:
<section>,<header>,<footer>, etc. - Add
class="code-section"to sections for identification.
Section ID naming
Use the same name as the component file (without extension), converted to kebab-case:
| Component file | Section ID |
|---|---|
Contact.astro |
<section id="contact"> |
AboutUs.astro |
<section id="about-us"> |
HeroSlider.astro |
<section id="hero-slider"> |
This ensures consistent, predictable IDs for navigation and anchor linking.
Reusable components
Extract shared pieces (Header, Footer, Buttons, Cards) into their own components. Always import content from front.yaml.
Styling
Tailwind CSS
Tailwind is the primary styling tool. Use utility classes directly in templates.
SCSS & custom properties
The creation script generates minimal SCSS files (resets and breakpoints only). No color, font, or typography files are auto-generated to avoid conflicts.
When you start styling:
- Cursor will prompt you for your CSS custom properties (colors, fonts, spacing, etc.).
- A
src/styles/_variables.scssfile is created with your design tokens in a:rootblock. - Import it in
_global.scssif needed.
Warning
Do not create _fonts.scss, _color-palette.scss, or _typography.scss automatically. Only create them if the client provides the specific styles.
Responsive design
Follow mobile-first principles. Use the breakpoint mixins from _breakpoints.scss:
@use 'breakpoints' as *;
.my-element {
padding: 1rem;
@include respond-to(min-tablet) {
padding: 2rem;
}
@include respond-to(min-desktop) {
padding: 3rem;
}
}
Available breakpoints:
| Name | Query |
|---|---|
mobile |
max-width: 767px |
tablet |
max-width: 1023px |
desktop |
max-width: 1439px |
desktop-lg |
min-width: 1440px |
min-tablet |
min-width: 768px |
min-desktop |
min-width: 1024px |
min-desktop-lg |
min-width: 1440px |
Icons
Font Awesome Pro
Font Awesome Pro is included via a Kit script in Base.astro (hardcoded kit code shared across all projects). Usage:
<i class="fa-solid fa-house" aria-hidden="true"></i>
<i class="fa-brands fa-github" aria-hidden="true"></i>
- Always add
aria-hidden="true"on decorative icons. - For interactive icons, add proper accessibility labels.
- Add project domains in the Font Awesome account settings.
Iconify
Iconify is also available via CDN (loaded in Base.astro):
TypeScript
All projects use TypeScript strict mode. Critical rules:
- Always explicitly type function parameters, array method callbacks, and component props.
- Never use implicit
anytypes.
// Good
array.map((item: FeatureType) => item.name);
// Good — Astro component props
interface Props {
title: string;
items: string[];
}
const { title, items }: Props = Astro.props;
Code quality
ESLint + Prettier
Both are pre-configured. Use the included npm scripts:
npm run lint # Check for issues
npm run lint:fix # Auto-fix issues
npm run format # Format all files with Prettier
HTML best practices
- Use proper heading hierarchy (
h1→h2→h3, etc.) - Ensure all images have proper
altattributes - Write semantic, accessible HTML
Working with Cursor (AI-assisted development)
Each project includes a .cursor/rules/general.mdc file and a docs/project_steps.md implementation plan. When developing with Cursor:
- Tell Cursor which step(s) to work on.
- Cursor follows the rules and step instructions.
- Once done, the step is marked
[x]in the plan. - You give the next instruction.
This ensures structured, predictable AI-assisted development.
Building a site from HTML + CSS custom properties
The most common workflow is to provide Cursor with a full HTML body (e.g. exported from a design tool or hand-crafted prototype) along with the project's CSS custom properties (colors, fonts, spacing, etc.). Cursor then reconstructs the site as proper Astro components.
What you provide:
- The HTML body content (with Tailwind classes, Font Awesome icons, etc.)
- Your CSS custom properties (e.g.
--accent-color,--font-family-body,--button-padding-x, etc.)
What Cursor does (enforced by the rules):
- Analyzes the HTML — identifies all sections, components, and reusable elements.
- Creates
_variables.scss— places your CSS custom properties in a:rootblock insrc/styles/_variables.scss. - Extracts all content to
front.yaml— every heading, paragraph, button label, link, and image URL is moved tosrc/data/front.yaml, organized by section. - Creates section components — each major HTML section becomes its own
.astrofile insrc/components/(e.g.Hero.astro,Features.astro,Contact.astro). - Creates reusable components — shared pieces like Header, Footer, and Cards are extracted into their own components.
- Assembles the page — imports all components into
src/pages/index.astro. - Preserves styling — Tailwind classes, CSS custom properties, and Font Awesome icons from the original HTML are kept intact.
The implementation plan (docs/project_steps.md) tracks this entire process step by step:
| Step | Task |
|---|---|
| Step 2 | Analyze HTML structure |
| Step 3 | Extract content to front.yaml |
| Step 4 | Create section components |
| Step 5 | Create reusable components |
| Step 7 | Implement main page |
| Step 8 | Add mobile menu functionality |
| Step 9 | Verify no hardcoded content remains |
| Step 10 | Style refinement |
| Step 11 | Accessibility and SEO check |
| Step 12 | Testing and finalization |
Tip
You don't have to provide the HTML and CSS variables all at once. You can feed sections incrementally and tell Cursor which steps to work on each time.