A Next.js image browsing application with infinite scroll and client-side image manipulation.
- Infinite Scrolling Gallery - Browse thousands of photos with automatic loading
- Client-Side Image Effects - Apply grayscale and blur filters in real-time
- Download Images - Save images with proper filenames
- Responsive Design - Mobile-first approach, works on all screen sizes
- Dark Mode - Automatic dark mode support
- Server-Side Rendering - Fast initial page loads with SEO optimization
- Shareable Permalinks - Direct links to individual images
- Accessible - Semantic HTML, ARIA labels, keyboard navigation
- Framework: Next.js 16 (App Router)
- Styling: Tailwind CSS 4
- Language: TypeScript
- Image Processing: Canvas API (no external dependencies)
- Image Source: Picsum Photos API
- Node.js 18+ and npm
# Install dependencies
npm install
# Run development server
npm run devOpen http://localhost:3000 to view the application.
# Create production build
npm run build
# Start production server
npm startapp/
page.tsx # Home page with infinite scroll grid
image/[id]/page.tsx # Dynamic image details page
loading.tsx # Loading skeleton
error.tsx # Error boundary
components/
ImageGrid.tsx # Infinite scroll container
ImageCard.tsx # Individual image card with navigation
ImageViewer.tsx # Full image display with state management
ImageToolbar.tsx # Download/grayscale/blur action buttons
ImageMetadata.tsx # Image details sidebar
lib/
picsum-api.ts # Picsum Photos API client
image-effects.ts # Canvas-based image manipulation utilities
types/
picsum.ts # TypeScript type definitions
Uses the Intersection Observer API to detect when the user scrolls near the bottom of the page, triggering automatic loading of more images.
All image effects (grayscale, blur) are processed client-side using the HTML5 Canvas API:
- Load the image with CORS enabled
- Draw it to a canvas element
- Apply pixel manipulation or CSS filters
- Export as a data URL for display/download
Downloads work by:
- Fetching the image and converting to a Blob
- Creating a temporary object URL
- Triggering a download with the proper filename
- Cleaning up the object URL to prevent memory leaks
This app uses the Picsum Photos API:
/v2/list- Paginated list of images/id/{id}/info- Single image metadata (undocumented)/id/{id}/{width}/{height}- Resized images on-the-fly
MIT