A modern, cloud-powered photo gallery application showcasing seamless integration between React frontend and AWS S3 cloud storage.
A fully responsive photo gallery web application that demonstrates cloud integration, modern frontend development, and professional UI/UX design. Built as a learning project to master AWS services, React development, and production deployment workflows.
Live Demo: View the Gallery
- Responsive Image Grid - Adaptive 3-column layout (desktop), 2-column (tablet), 1-column (mobile)
- Smooth Scroll Animations - Images fade in elegantly as you scroll using Intersection Observer API
- Interactive Lightbox Viewer - Full-screen image viewing with sleek dark overlay
- Keyboard Navigation - Arrow keys (←/→) to browse images, ESC to close
- Hover Effects - Images zoom and reveal metadata on hover
- Real-time Search - Instant filtering by image filename
- Category Filtering - Toggle between All, Nature, Architecture, and Abstract
- Image Download - One-click download from lightbox viewer
- Loading States - Skeleton screens for optimal perceived performance
- Empty State Handling - User-friendly messages when no results found
- AWS S3 Storage - Scalable, cost-effective image hosting
- CloudFront CDN - Global content delivery with HTTPS
- Lazy Loading - Images load on-demand for faster initial page load
- Optimized Build - Vite bundler for lightning-fast development and production builds
- Modern React - Hooks (useState, useEffect, custom hooks) and functional components
Clean, responsive grid layout with category badges and hover effects
Full-screen image viewer with navigation controls and metadata
Fully responsive design adapts beautifully to all screen sizes
| Category | Technologies |
|---|---|
| Frontend Framework | React 18 |
| Build Tool | Vite 7 |
| Styling | Tailwind CSS 3 |
| Cloud Storage | AWS S3 |
| CDN | AWS CloudFront |
| API Integration | AWS SDK for JavaScript v3 |
| Deployment | AWS S3 Static Hosting |
| Version Control | Git & GitHub |
┌─────────────────┐
│ User Browser │
└────────┬────────┘
│
↓ HTTPS
┌─────────────────┐
│ CloudFront │ ← Global CDN (Fast delivery worldwide)
└────────┬────────┘
│
↓
┌─────────────────┐
│ S3 (Website) │ ← React App (HTML, CSS, JS)
└─────────────────┘
│
│ AWS SDK
↓
┌─────────────────┐
│ S3 (Images) │ ← Image Storage (JPEG, PNG)
└─────────────────┘
photo-gallery-app/
├── src/
│ ├── components/ # React Components
│ │ ├── PhotoCard.jsx # Individual image card with hover effects
│ │ ├── CategoryFilter.jsx # Category filter buttons
│ │ ├── Lightbox.jsx # Full-screen image viewer
│ │ ├── SearchBar.jsx # Search input with clear button
│ │ ├── LoadingSkeleton.jsx # Loading placeholder components
│ │ └── EmptyState.jsx # No results message
│ ├── services/
│ │ └── s3Service.js # AWS S3 API integration
│ ├── hooks/
│ │ └── useScrollAnimation.js # Custom scroll-triggered animation hook
│ ├── App.jsx # Main application component
│ ├── main.jsx # React entry point
│ └── index.css # Tailwind directives & global styles
├── public/ # Static assets
├── .env.example # Environment variables template
├── .gitignore # Git ignore rules
├── index.html # HTML template
├── package.json # Dependencies & scripts
├── tailwind.config.js # Tailwind configuration
├── postcss.config.js # PostCSS configuration
├── vite.config.js # Vite bundler configuration
└── README.md # This file
- Clone the repository
git clone https://github.com/fadeel7/Project2-photo-gallery-app.git
cd Project2-photo-gallery-app- Install dependencies
npm install-
Set up environment variables
Create a
.envfile in the root directory:
VITE_AWS_REGION=us-east-1
VITE_AWS_ACCESS_KEY_ID=your_access_key_here
VITE_AWS_SECRET_ACCESS_KEY=your_secret_key_here
VITE_S3_BUCKET_NAME=your_bucket_name_here**Security Note:** Never commit `.env` to Git! It's already in `.gitignore`.
- Run development server
npm run dev-
Open in browser
Navigate to
http://localhost:5173
npm run buildThis generates an optimized production build in the dist/ folder.
- Create S3 bucket with static website hosting enabled
- Configure bucket policy for public read access
- Upload
dist/contents to the bucket - Set up CloudFront (optional but recommended for HTTPS and CDN)
Detailed deployment guide: View Documentation
Switch between image categories (Nature, Architecture, Abstract) with smooth transitions. Active category is highlighted with a gradient button style.
Real-time client-side search that filters images by filename. Includes a clear button (×) that appears when text is entered.
- Click any image to open full-screen view
- Navigate with arrow keys (←/→) or on-screen buttons
- Download images with single click
- Displays image metadata (filename, category, size)
- Shows current position (e.g., "3 / 15")
- Close with ESC key or click outside
Uses Intersection Observer API to detect when images enter viewport and trigger fade-in animations. Improves perceived performance and adds polish.
- Desktop (>1024px): 3-column grid
- Tablet (768px-1024px): 2-column grid
- Mobile (<768px): 1-column grid
- Touch-friendly interactions on mobile devices
✅ Environment Variables - AWS credentials stored in .env (not in repo)
✅ IAM Permissions - Read-only S3 access for frontend
✅ CORS Configuration - Properly configured for browser requests
✅ Bucket Policies - Public read access only for images
✅ HTTPS - CloudFront provides SSL/TLS encryption
✅ No Hardcoded Secrets - All sensitive data in environment variables
- ✓ Verify AWS credentials in
.envare correct - ✓ Check S3 bucket CORS policy allows your domain
- ✓ Ensure S3 bucket policy permits public read (
s3:GetObject) - ✓ Confirm bucket region matches
VITE_AWS_REGION
- ✓ Delete
node_modules/andpackage-lock.json - ✓ Run
npm installagain - ✓ Check Node.js version:
node --version(should be v16+)
- ✓ Create invalidation for
/*in CloudFront console - ✓ Wait 5-10 minutes for distribution to update
- Lighthouse Score: 95+ (Performance, Accessibility, Best Practices)
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3s
- Bundle Size: ~150KB (gzipped)
Through this project, I gained hands-on experience with:
- AWS Services - S3 storage, CloudFront CDN, IAM permissions
- Modern React - Hooks, component composition, state management
- Tailwind CSS - Utility-first styling, responsive design
- Build Tools - Vite configuration and optimization
- Deployment - Production builds, static hosting, CDN setup
- Security - Environment variables, IAM policies, CORS
- Version Control - Git workflows, GitHub collaboration
- Upload Feature - Allow users to upload images directly from UI
- User Authentication - AWS Cognito for user accounts
- Private Galleries - User-specific image collections
- Image Optimization - AWS Lambda for automatic resizing
- Thumbnails - Generate low-res previews for faster loading
- Tags & Albums - Organize images with custom tags
- Social Sharing - Share images on social media
- Dark Mode - Toggle between light/dark themes
- Drag & Drop Upload - Intuitive file upload interface
This project is open source and available under the MIT License.
Fadeel Darkwa
- GitHub: @fadeel7
- Images: Sample images from Unsplash and Pexels
- Icons: SVG icons designed inline with Heroicons style
- Inspiration: Modern photo gallery designs from Dribbble and Behance
- Learning Resources: AWS Documentation, React Docs, Tailwind CSS Docs
Contributions, issues, and feature requests are welcome!
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
If you found this project helpful or learned something from it, please give it a ⭐️!
Built as part of my cloud + frontend development learning journey