Overview
The Drakk3 Portfolio uses Astro as the primary framework with React for interactive components. This hybrid approach combines the performance of static site generation with the interactivity of a modern JavaScript framework.How Astro and React Work Together
Astro and React integration follows a static-first philosophy:Default: Static HTML
All components render to static HTML at build time. No JavaScript is shipped to the browser by default.
Opt-in to interactivity
Use client directives (like
client:load) to hydrate React components on the client.Configuration
The React integration is configured inastro.config.mjs:12:
astro.config.mjs
The
@astrojs/react integration allows you to use React components (.tsx, .jsx) alongside Astro components (.astro).Client Directives
Client directives tell Astro when and how to hydrate a React component on the client side.The client:load Directive
The most common directive in this project is client:load, used for the Contact form:
src/pages/index.astro:19
- Hydrates the component immediately on page load
- Loads the React runtime and component JavaScript as soon as possible
- Ensures the component is interactive ASAP
- Components that are immediately visible (above the fold)
- Critical interactive elements like forms, navigation menus
- Components where delayed hydration would be noticeable to users
Real-World Example: Contact Form
The Contact component requires immediate interactivity because:- Form state management - Uses
useStatefor form status (src/components/Contact.tsx:10) - User interactions - Handles form submission immediately
- Visual feedback - Shows loading states with
useTransition(src/components/Contact.tsx:11)
src/components/Contact.tsx:9
Other Client Directives
Whileclient:load is used in this project, Astro provides other directives for different use cases:
- client:idle
- client:visible
- client:media
- client:only
Hydrates the component when the browser is idle (uses Best for: Analytics, chat widgets, non-critical interactive features.
requestIdleCallback).Performance Comparison
| Directive | When Hydrated | JavaScript Load Time | Use Case |
|---|---|---|---|
client:load | Immediately | ~0s | Critical interactive components |
client:idle | When browser idle | ~0.5-2s | Non-critical features |
client:visible | When scrolled into view | Varies | Below-fold content |
client:media | When media query matches | Varies | Responsive components |
client:only | Client-side only | ~0s | Browser-dependent components |
Choosing Astro vs React Components
Decision Flow
Practical Examples from This Project
Navbar Component
Technology: AstroWhy: Static navigation with anchor links. No JavaScript needed.
Contact Component
Technology: React +
client:loadWhy: Requires form state, validation, submission handling, and dynamic UI updates.Passing Props Between Astro and React
Serializable Props
You can pass data from Astro to React components, but props must be JSON-serializable:Example: Passing data to React
- ✅ Strings, numbers, booleans
- ✅ Arrays and objects (plain)
- ✅
nullandundefined
- ❌ Functions
- ❌ Class instances
- ❌ Symbols
- ❌ React components
Prop Types
Define TypeScript interfaces for type safety:Example: React component with props
Path Alias Configuration
The@/ alias simplifies imports across Astro and React components:
astro.config.mjs:16
Usage in React Components
src/components/Contact.tsx:2
Usage in Astro Components
Example Astro component
The
@/ alias works in both .astro and .tsx files thanks to Vite’s resolver configuration.Component Communication Patterns
Parent Astro → Child React
Pass data down via props (as shown above).Sibling React Components
Use React context or state management libraries:Example: Context provider in React
Astro ↔ React Communication
Solutions:- Pass initial data via props during build
- Use URL state (query params, hash) for cross-component communication
- Use localStorage/sessionStorage for persistent state
- Fetch shared data from an API on the client
Best Practices
Start Static
Default to Astro components. Only reach for React when you need interactivity.
Choose the Right Directive
Use
client:visible or client:idle instead of client:load when possible to reduce initial JavaScript.Keep Props Simple
Only pass JSON-serializable data between Astro and React components.
Use TypeScript
Define interfaces for React component props to catch errors at build time.
Common Pitfalls
1. Forgetting the Client Directive
2. Passing Functions as Props
3. Using Browser APIs in Astro Components
Next Steps
Architecture Overview
Understand the overall project architecture and structure
Tailwind v4 Configuration
Learn about Tailwind CSS v4 native configuration