A beautiful, responsive portfolio website built specifically for artists to showcase their creative work. This Next.js-powered application combines elegant design with powerful features like offline support, real-time image management, and smooth animations to create a professional online presence.
- Stunning Gallery - Browse artwork in a responsive grid layout
- Full-Screen Viewer - Immersive image viewing with swipe navigation
- Artist Bio - Learn about the artist's journey and background
- Contact Form - Easy communication directly through the website
- PWA Support - Install as an app and access offline
- Secure Login - Firebase authentication protects your admin panel
- Easy Upload - Drag-and-drop image uploads with progress tracking
- Content Management - Add labels, descriptions, and showcase flags
- Real-Time Updates - Changes appear instantly across the site
- Lightning Fast - Next.js with optimized images and caching
- Fully Responsive - Beautiful on mobile, tablet, and desktop
- Smooth Animations - Framer Motion for buttery transitions
- Real-Time Sync - Firebase Firestore for live data updates
- SEO Optimized - Open Graph and Twitter Card support
- TypeScript - Type-safe codebase for reliability
Frontend: Next.js 11, React 17, TypeScript
Styling: Tailwind CSS
Backend: Firebase (Firestore, Storage, Auth)
Animations: Framer Motion, React Reveal
Components: Swiper (Carousel)
PWA: next-offline
- Node.js 14+ and npm/yarn
- Firebase project with Firestore, Storage, and Authentication enabled
- Clone the repository
git clone https://github.com/satvikvirmani/nextjs-artist-portfolio.git
cd nextjs-artist-portfolio- Install dependencies
yarn install
# or
npm install-
Configure Firebase
Update
backend/firebase-config.tswith your Firebase credentials:
const config = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID",
measurementId: "YOUR_MEASUREMENT_ID"
};-
Update mock data
Create
mock/mock.tswith your information:
export const data = {
name: "Your Name",
job: "Your Title",
email: "your.email@example.com",
facebook_link: "https://facebook.com/yourprofile",
instagram_link: "https://instagram.com/yourprofile",
aboutme_para1: "First bio paragraph...",
aboutme_para2: "Second bio paragraph..."
};-
Update contact form
In
components/Contact.tsx, change the FormSubmit email:
action="https://formsubmit.co/YOUR_EMAIL@example.com"- Run development server
yarn dev
# or
npm run devVisit http://localhost:3000 to see your portfolio! π
nextjs-artist-portfolio/
βββ backend/
β βββ firebase-config.ts # Firebase initialization
βββ components/
β βββ Bio.tsx # Artist biography section
β βββ Contact.tsx # Contact form
β βββ Footer.tsx # Site footer
β βββ Gallery.tsx # Full-screen image viewer
β βββ Hero.tsx # Homepage hero section
β βββ ImageComponent.tsx # Individual image card
β βββ Layout.tsx # Page layout wrapper
β βββ ListMobile.tsx # Mobile navigation menu
β βββ LoginForm.tsx # Admin authentication
β βββ Navbar.tsx # Navigation bar
β βββ Progressbar.tsx # Upload progress indicator
β βββ Showcase.tsx # Portfolio grid
β βββ UploadForm.tsx # Admin upload interface
βββ hooks/
β βββ useDatabase.ts # Fetch images from Firestore
β βββ useLogin.ts # Authentication helper
β βββ useStorage.ts # Handle file uploads
β βββ uniqueFunction.ts # Calculate image dimensions
βββ pages/
β βββ _app.tsx # Custom App component
β βββ _document.tsx # Custom Document
β βββ index.tsx # Homepage
β βββ portfolio.tsx # Full portfolio page
β βββ bio.tsx # Biography page
β βββ contact.tsx # Contact page
β βββ admin.tsx # Admin panel
βββ public/
β βββ icons/ # PWA app icons
β βββ manifest.json # PWA manifest
βββ mock/
βββ mock.ts # Artist data (create this!)
Edit tailwind.config.js and component styling. Default theme uses cream (#f8edeb) and pink (#fcd5ce).
Replace URLs in Hero.tsx and Bio.tsx with your Cloudinary/hosting URLs.
All components use Tailwind's grid system - adjust column spans for different layouts.
- Push your code to GitHub
- Import project in Vercel
- Environment variables are not needed (Firebase config is client-side)
- Deploy! β¨
yarn build
yarn start- Browse the homepage to see featured artwork
- Click "Portfolio" to view all pieces
- Click any image to open full-screen gallery
- Use arrow keys or swipe to navigate
- Visit "Bio" to learn about the artist
- Use "Contact" form to send a message
- Navigate to
/admin - Log in with your Firebase credentials
- Upload new images with labels and descriptions
- Check "Show in Showcase" to feature on homepage
- Images appear instantly on the live site
- Admin route is protected by Firebase Authentication
- Use Firebase Console to create admin users
- Never commit Firebase credentials to public repos
- Consider adding custom claims for role-based access
Images not loading?
- Check Firebase Storage security rules
- Verify image URLs are publicly accessible
Upload failing?
- Ensure Firebase Storage is enabled
- Check file size (recommended < 5MB)
- Verify file format (PNG/JPEG only)
Build errors?
- Delete
.nextfolder andnode_modules - Run
yarn installagain - Check Node.js version (14+ required)
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
Feel free to check the issues page.
- Lighthouse Score: 95+ (Performance, Accessibility, Best Practices, SEO)
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3s
- PWA: Fully installable with offline support
This project is MIT licensed.
Copyright (c) 2021 Satvik Virmani
- Twitter: @satvikvirmani
- Medium: satvikvirmani.medium.com
- Email: virmanisatvik01@gmail.com
- Next.js - The React framework
- Firebase - Backend services
- Tailwind CSS - Utility-first CSS
- Framer Motion - Animation library
- Swiper - Touch slider
Give a βοΈ if this project helped you create an amazing portfolio!
Made with β€οΈ and β
