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

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

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

  1. Start with content structure - Define your collections early
  2. Plan for performance - Use Astro’s island architecture wisely
  3. Keep it simple - Don’t over-engineer the initial implementation
  4. 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!