Building My Developer Portfolio with Astro


Project Overview

This portfolio website was built with Astro, focusing on performance, SEO, and maintainability. Hereโ€™s how I approached the development process.

Key Features

  • โšก๏ธ Perfect Lighthouse score
  • ๐Ÿ“ฑ Responsive design
  • ๐ŸŽจ Dark/Light mode
  • ๐Ÿ“ Markdown blog posts
  • ๐Ÿ” SEO optimized
  • ๐Ÿ“Š Analytics integration

Implementation Details

Hereโ€™s how I implemented the dark mode toggle:

// src/components/ThemeToggle.astro
---
const { class: className } = Astro.props;
---

<button
  id="themeToggle"
  class={`theme-toggle ${className}`}
  title="Toggle dark mode"
>
  <svg width="20" height="20" viewBox="0 0 20 20">
    <!-- Sun icon -->
    <path
      class="sun"
      fill-rule="evenodd"
      d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
    />
    <!-- Moon icon -->
    <path
      class="moon"
      fill-rule="evenodd"
      d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"
    />
  </svg>
</button>

<script>
  document.addEventListener('astro:page-load', () => {
    const theme = (() => {
      if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
        return localStorage.getItem('theme');
      }
      if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        return 'dark';
      }
      return 'light';
    })();

    if (theme === 'light') {
      document.documentElement.classList.remove('dark');
    } else {
      document.documentElement.classList.add('dark');
    }

    window.localStorage.setItem('theme', theme);

    const handleToggleClick = () => {
      const element = document.documentElement;
      element.classList.toggle('dark');

      const isDark = element.classList.contains('dark');
      localStorage.setItem('theme', isDark ? 'dark' : 'light');
    };

    document
      .getElementById('themeToggle')
      ?.addEventListener('click', handleToggleClick);
  });
</script>

<style>
  .theme-toggle {
    border: 0;
    background: none;
    cursor: pointer;
    padding: 0;
  }
  .sun { display: var(--sun-display, block); }
  .moon { display: var(--moon-display, none); }
  :global(.dark) .sun { display: var(--sun-display, none); }
  :global(.dark) .moon { display: var(--moon-display, block); }
</style>

Performance Optimizations

  1. Static site generation with Astro
  2. Image optimization
  3. Minimal JavaScript
  4. CSS optimization

Screenshots

Homepage Homepage design showcasing projects

Blog Section Blog section with featured posts

Future Enhancements

  1. Add search functionality
  2. Implement comments system
  3. Add project filtering
  4. Create an RSS feed