Note: This project now uses Next.js API routes (for the contact form), so it's no longer a static export. Image optimization can be enabled if deploying to Vercel.
- Images are set to
unoptimized: truefor compatibility - For better performance, consider the options below:
Before building, optimize your images:
-
Use a tool like Sharp or ImageMagick:
# Install sharp bun add -d sharp # Create optimized versions of images # Convert to WebP format
-
Use online tools:
-
Recommended image formats:
- WebP (best compression, good browser support)
- AVIF (best compression, newer browsers)
- JPEG (fallback, universal support)
- Sign up at Cloudinary
- Upload images to Cloudinary
- Update
next.config.ts:
const nextConfig: NextConfig = {
output: "export",
images: {
loader: "custom",
loaderFile: "./lib/cloudinary-loader.ts",
},
trailingSlash: true,
};- Create
lib/cloudinary-loader.ts:
export default function cloudinaryLoader({ src, width, quality }: {
src: string;
width: number;
quality?: number;
}) {
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`];
return `https://res.cloudinary.com/YOUR_CLOUD_NAME/image/upload/${params.join(',')}${src}`;
}- Update image paths in
data/models.jsonto use Cloudinary URLs
Similar setup to Cloudinary, using Imgix's image optimization service.
If deploying to Vercel, you can use their image optimization:
- Remove
output: "export"fromnext.config.ts - Set
images.unoptimized: false - Deploy to Vercel - they handle optimization automatically
-
Enable GitHub Pages:
- Go to your repository Settings → Pages
- Source: Select "GitHub Actions"
-
Set up secrets (if using Formspree):
- Go to Settings → Secrets and variables → Actions
- Add secret:
NEXT_PUBLIC_FORMSPREE_ENDPOINTwith your Formspree endpoint
-
Push to GitHub:
- The workflow (
.github/workflows/deploy.yml) will automatically build and deploy on every push tomain
- The workflow (
-
Access your site:
- If repository is
username.github.io:https://username.github.io - If repository has a different name:
https://username.github.io/repository-name - Note: If deploying to a subdirectory, you'll need to add
basePathtonext.config.ts(see below)
- If repository is
-
Build the site:
bun run build
-
Enable GitHub Pages:
- Go to repository Settings → Pages
- Source: Select a branch (e.g.,
gh-pages) - Folder: Select
/ (root)or create agh-pagesbranch
-
Deploy the
outfolder:# Option 1: Use gh-pages package bun add -d gh-pages bunx gh-pages -d out # Option 2: Manual push git checkout --orphan gh-pages git rm -rf . cp -r out/* . git add . git commit -m "Deploy to GitHub Pages" git push origin gh-pages
If your site is at username.github.io/repository-name, update next.config.ts:
const nextConfig: NextConfig = {
output: "export",
basePath: "/repository-name", // Replace with your repository name
images: {
unoptimized: true,
},
trailingSlash: true,
};-
Free Tier (Hobby Plan):
- ✅ Unlimited personal projects
- ✅ 100GB bandwidth/month
- ✅ Serverless functions (API routes)
- ✅ Automatic HTTPS
- ✅ Custom domains
- ✅ Preview deployments
- ✅ Analytics (limited)
- Perfect for most portfolios and small projects!
-
Pro Plan ($20/month):
- Everything in Hobby
- More bandwidth (1TB)
- Team collaboration
- Advanced analytics
- Priority support
For your modeling portfolio, the free tier is more than enough!
-
Push your code to GitHub (if not already):
git add . git commit -m "Add SMTP contact form" git push origin main
-
Sign up/Login to Vercel:
- Go to vercel.com
- Sign up with GitHub (recommended) or email
-
Import your project:
- Click "Add New..." → "Project"
- Import your GitHub repository
- Vercel will auto-detect Next.js settings
-
Configure Environment Variables:
- In project settings, go to "Environment Variables"
- Add the following (from
.env.example):SMTP_HOST=smtp.zoho.com SMTP_PORT=587 SMTP_USER=your-zoho-email@zoho.com SMTP_PASSWORD=your-app-specific-password RECIPIENT_EMAIL=where-to-receive@example.com - Make sure to add them for Production, Preview, and Development environments
-
Deploy:
- Click "Deploy"
- Vercel will build and deploy automatically
- Your site will be live at
your-project.vercel.app
-
Custom Domain (Optional):
- Go to Project Settings → Domains
- Add your custom domain
- Follow DNS configuration instructions
- ✅ API Routes Work: Since we removed
output: "export", your/api/contactroute will work as a serverless function - ✅ No Build Changes Needed: Vercel auto-detects Next.js and uses the correct build settings
- ✅ Environment Variables: Make sure to add all SMTP credentials in Vercel dashboard
- ✅ Automatic Deployments: Every push to
mainbranch triggers a new deployment
- Build command:
bun run build - Publish directory:
out - Deploy
- Build command:
bun run build - Build output directory:
out - Deploy
- Build:
bun run build - Upload
out/directory to S3 bucket - Configure CloudFront distribution
- Enable CloudFront caching
- Optimize all images (WebP format recommended)
- Compress videos (use H.264 codec)
- Enable CDN caching
- Use lazy loading (already implemented)
- Minimize JavaScript bundle (already optimized)
- Enable gzip/brotli compression on server
- Set proper cache headers
- Featured images: 1200x1600px (3:4 aspect ratio)
- Gallery images: 1080x1440px (3:4 aspect ratio)
- Thumbnails: 300x400px (3:4 aspect ratio)
- Video thumbnails: 640x853px (3:4 aspect ratio)
- Format: MP4 (H.264 codec)
- Resolution: 1080p max
- File size: Keep under 10MB per video
- Duration: 15-30 seconds for portfolio videos
- Poster images: Always provide thumbnail images