Overview
Proyecto Renacer uses Astro components for building reusable UI elements. All components are located in /src/components/ and can be imported into pages or other components.
Component Architecture
Components follow Astro’s single-file component format:
---
// TypeScript/JavaScript logic
interface Props {
title : string ;
}
const { title } = Astro . props ;
---
<!-- HTML template -->
< div class = "component" >
< h2 > { title } </ h2 >
</ div >
<!-- Scoped or global styles -->
< style >
.component { /* styles */ }
</ style >
Available Components
Button Multi-variant button with link support
ButtonTransparent Transparent button variant
CardLg Large card container
CardMd Medium card with image and overlay
CardSm Small info card with slot support
Header Site-wide navigation header
Navigation Dynamic navigation menu
NavItem Individual navigation item
Head SEO meta tags component
OpenGraph Open Graph social media tags
Welcome Welcome/hero component
Inprogress Work-in-progress indicator
Multi-purpose button with various styles and link support.
Component Code
src/components/Button.astro
---
interface Props {
type : "primary" | "secondary" | "dark" | "light" | "whatsapp" | "facebook" ;
link ?: string ;
rounded ?: "plain" | "lg" | "full" | "pill" ;
}
const { type = "primary" , link , rounded = "lg" } = Astro . props ;
const buttonClass = {
primary: "bg-primary text-white hover:bg-primary/90" ,
secondary: "bg-secondary text-white hover:bg-secondary/90" ,
dark: "bg-slate-900 dark:bg-slate-700 text-white hover:bg-slate-800" ,
light: "bg-white border-2 border-primary/50 text-slate-800 hover:bg-light" ,
whatsapp: "bg-emerald-600 text-white hover:bg-emerald-700" ,
facebook: "bg-white border-2 border-primary/50 text-slate-800 hover:bg-light" ,
}[ type ];
const roundedClass = {
plain: "rounded-xs" ,
lg: "rounded-lg" ,
full: "rounded-2xl" ,
pill: "rounded-4xl" ,
}[ rounded ]
---
< a href = { link } >
< button
class = { buttonClass +
" px-8 py-4 font-bold text-lg hover:scale-105 transition-transform flex items-center gap-2 " + roundedClass }
>
< slot />
</ button >
</ a >
Usage
< Button type = "primary" link = "/proyecto" >
Solicita información
< span class = "material-symbols-outlined" > arrow_forward </ span >
</ Button >
< Button type = "whatsapp" rounded = "full" link = "https://wa.me/593999730617" >
< span class = "material-symbols-outlined" > chat </ span >
Contáctanos por WhatsApp
</ Button >
Props
type
string
default: "primary"
required
Button style variant: primary, secondary, dark, light, whatsapp, or facebook
URL to navigate to when clicked
Border radius: plain, lg, full, or pill
Card Components
CardMd - Medium Card
Displays an image with overlay text, used for showcasing locations.
src/components/CardMd.astro
---
import { Image } from 'astro:assets' ;
import img from "../assets/mockImg.webp" ;
---
< div
class = "relative w-full aspect-4/3 rounded-3xl overflow-hidden shadow-2xl bg-neutral-beige/20 group"
>
< Image
class = "object-cover w-full h-full"
src = { img }
alt = "Terrenos en Ambato"
/>
< div class = "absolute inset-0 bg-linear-to-t from-black/40 to-transparent" >
</ div >
< div class = "absolute bottom-6 left-6 text-white" >
< span
class = "bg-secondary/90 backdrop-blur px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider"
> Proyecto Social </ span
>
< p class = "mt-2 text-xl font-bold" > Sector Chaupi San Luis </ p >
</ div >
</ div >
Features:
Optimized image with astro:assets
Gradient overlay for text readability
Badge and location text
4:3 aspect ratio
Usage:
CardSm - Small Card
Info card with title, text, and customizable slot for icons.
src/components/CardSm.astro
---
interface Props {
title : string ;
text : string ;
}
const { title , text } = Astro . props ;
---
< div
class = "p-8 rounded-2xl bg-light dark:bg-dark border border-primary/20 hover:shadow-xl transition-all"
>
< slot />
< h3 class = "text-xl font-bold mb-3" > { title } </ h3 >
< p class = "text-slate-600 dark:text-slate-400" >
{ text }
</ p >
</ div >
Usage:
< CardSm
title = "Vivienda Social"
text = "Respaldo total del MIDUVI enfocado en familias de escasos recursos."
>
< div class = "w-14 h-14 rounded-xl bg-primary/10 text-primary flex items-center justify-center mb-6" >
< span class = "material-symbols-outlined text-3xl" > real_estate_agent </ span >
</ div >
</ CardSm >
Props:
title (string, required) - Card heading
text (string, required) - Card description
Default slot - Icon or image content
Persistent navigation header with logo and menu.
src/components/Header.astro
---
import Navigation from "./Navigation.astro" ;
const listItems = [
{ tag: "Inicio" , link: "/" },
{ tag: "Proyecto" , link: "/proyecto" },
{ tag: "Noticias" , link: "/noticias" },
{ tag: "Requisitos" , link: "/requisitos" },
{ tag: "Contacto" , link: "/contacto" },
];
---
< header
class = "sticky top-0 z-50 w-full px-4 py-4 flex items-center justify-between
border-b border-black/30 bg-background-light/80 backdrop-blur-md
dark:bg-background-dark/80 md:px-20 lg:px-40"
>
< div class = "flex items-center gap-2 text-primary" >
< span class = "material-symbols-outlined text-3xl" > home_pin </ span >
< h2 class = "text-xl font-black tracking-tighter uppercase" > RENACER </ h2 >
</ div >
< Navigation listItems = { listItems } />
< div class = "flex items-center gap-4" >
< a href = "/como-ser-socio"
class = "bg-primary hover:bg-primary/90 text-white px-6 py-2 rounded-lg
text-sm font-bold transition-all shadow-md"
>
Como ser Socio
</ a >
</ div >
</ header >
Features:
Sticky positioning (sticky top-0)
Backdrop blur for glassmorphism effect
Responsive padding
Dark mode support
Material icons for logo
CTA button to membership page
Usage:
Site-wide footer with navigation, contact info, and social links.
src/components/Footer.astro
< footer class = "bg-slate-900 text-white px-4 md:px-20 lg:px-40 py-16" >
< div class = "grid md:grid-cols-4 gap-12 mb-12" >
< div class = "col-span-2" >
< div class = "flex items-center gap-2 text-primary mb-6" >
< span class = "material-symbols-outlined text-3xl" > home_pin </ span >
< h2 class = "text-2xl font-black tracking-tighter uppercase" > RENACER </ h2 >
</ div >
< p class = "text-slate-400 max-w-sm" >
Proyecto de vivienda social enfocado en brindar dignidad y estabilidad...
</ p >
</ div >
<!-- Navigation links, contact info, social media -->
</ div >
</ footer >
Sections:
Brand logo and description
Site navigation links
Contact information (email, phone, location)
Social media links (Facebook)
Usage:
Navigation Components
Navigation
Dynamic navigation menu renderer.
src/components/Navigation.astro
---
interface Props {
listItems : Array <{ tag : string , link : string }>;
}
const { listItems } = Astro . props ;
---
< nav >
{ listItems . map ( item => (
< a href = { item . link } > { item . tag } </ a >
)) }
</ nav >
NavItem
Individual navigation link item.
src/components/NavItem.astro
---
interface Props {
tag : string ;
link : string ;
}
const { tag , link } = Astro . props ;
---
< a href = { link } > { tag } </ a >
SEO Components
Head
Common meta tags and SEO configuration.
src/components/Head.astro
<!-- Favicon links -->
< link rel = "icon" type = "image/svg+xml" href = "/favicon.svg" />
< link rel = "icon" type = "image/x-icon" href = "/favicon.ico" />
<!-- Fonts -->
< link rel = "preconnect" href = "https://fonts.googleapis.com" />
<!-- Additional meta tags -->
< meta name = "robots" content = "index,follow" />
< meta name = "generator" content = { Astro . generator } />
OpenGraph
Social media sharing tags.
src/components/OpenGraph.astro
---
interface Props {
OGTitle : string ;
OGDescription : string ;
OGImage ?: string ;
}
const { OGTitle , OGDescription , OGImage } = Astro . props ;
---
< meta property = "og:title" content = { OGTitle } />
< meta property = "og:description" content = { OGDescription } />
< meta property = "og:image" content = { OGImage } />
< meta property = "og:type" content = "website" />
< meta name = "twitter:card" content = "summary_large_image" />
Component Best Practices
Use TypeScript interfaces for props
Define clear prop types for better DX and type safety: interface Props {
title : string ;
description ?: string ;
}
Use destructuring with defaults: const { type = "primary" , rounded = "lg" } = Astro.props;
Use slots for flexibility
Allow content injection with <slot />: < div class = "card" >
< slot />
< h3 > { title } </ h3 >
</ div >
Each component should have a single, clear responsibility.
Avoid custom CSS when Tailwind utilities work. Use scoped styles only for complex cases.
Creating New Components
Create file
Add a new .astro file in /src/components/: touch src/components/MyComponent.astro
Define structure
Add frontmatter, template, and optional styles: ---
interface Props {
title : string ;
}
const { title } = Astro . props ;
---
< div > { title } </ div >
Import and use
Import in pages or other components: ---
import MyComponent from "../components/MyComponent.astro" ;
---
< MyComponent title = "Hello" />
Next Steps
Layouts Learn about page layout templates
Pages See how components are used in pages