Building This Portfolio with Astro
My experience learning Astro and building a modern portfolio with photo galleries, blogs, and interactive components.
Why Astro?
When I decided to expand my portfolio beyond just a developer showcase, I needed a framework that could handle:
- Static site generation for excellent performance
- Multiple content types (photos, blog posts, project showcases)
- React components for interactive features
- Modern developer experience with hot reloading and TypeScript
Astro checked all these boxes and more.
Key Features I Implemented
Content Collections
One of Astro’s standout features is Content Collections. Instead of manually managing markdown files, I can define schemas for different content types:
const blog = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.date(),
tags: z.array(z.string()).default([]),
// ... more fields
}),
});
This gives me type safety, validation, and a clean API for querying content.
Component Architecture
I’m using a hybrid approach:
- Astro components for layouts and static content
- React components for interactive features like the photo gallery and challenge tracker
- Proper hydration only where needed with
client:load
Photo Gallery with Swiper
The photo gallery was particularly fun to build. I integrated Swiper.js with React to create:
- Touch-friendly navigation
- Thumbnail previews
- Zoom functionality
- Photo metadata display
- Responsive design
Performance Optimizations
Astro’s default approach of shipping zero JavaScript unless explicitly needed means the site loads incredibly fast. When I do need JavaScript for interactive components, it’s only loaded where necessary.
Challenges & Solutions
Image Optimization
Managing photos for web display required careful consideration of:
- Multiple sizes for responsive images
- Proper compression without quality loss
- Lazy loading for gallery performance
Navigation Complexity
Creating a navigation that works both for the single-page portfolio and multi-page blog/gallery sections required some clever conditional logic.
Content Organization
Structuring content collections for photos, blog posts, and challenge entries while maintaining relationships between them took some planning.
What’s Next?
I’m planning to add:
- RSS feed for the blog
- Search functionality
- Photo tagging and filtering
- Integration with a headless CMS for easier content management
Lessons Learned
- Start with content structure - Define your collections early
- Plan for performance - Use Astro’s island architecture wisely
- Keep it simple - Don’t over-engineer the initial implementation
- Document as you go - Both in code and in blog posts like this one
Building this portfolio has been a great way to learn Astro while creating something useful. The framework’s approach to partial hydration and content-first development really resonates with my goals for this project.
Check out the source code or browse the photo gallery to see the results!