22 Build for Static vs SSR
22.1 Static Export (Like Flutter Web)
This generates pure HTML/CSS/JS files that can be deployed to static hosting (Netlify, Firebase Hosting, etc.) - similar to Flutter web builds.
22.1.1 Configuration
next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
// Optional: if deploying to subdirectory
// basePath: '/my-app',
// images: {
// unoptimized: true, // Required for static export
// }
}
.exports = nextConfig module
22.1.2 Build Command
npm run build
Output location: .next/
folder, but Next.js also creates an out/
directory:
my-nextjs-app/
├── out/ ← Deploy this folder! (like Flutter's build/web)
│ ├── index.html
│ ├── about.html
│ ├── _next/
│ │ ├── static/
│ │ └── ...
│ └── ...
├── .next/ ← Intermediate build files
└── ...
22.1.3 Deployment
# Deploy to Firebase Hosting (you're familiar with this!)
firebase deploy
# Or to Netlify
netlify deploy --prod --dir=out
22.2 Server-Side Deployment (Full Next.js Features)
This requires a Node.js server to run. Supports all Next.js features like SSR, ISR, API routes.
22.2.1 Configuration
next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone', // Optional: creates optimized server bundle
// Or omit 'output' for default server build
}
.exports = nextConfig module
22.2.2 Build Command
npm run build
Output location: .next/
directory only (no out/
folder)
my-nextjs-app/
├── .next/ ← Entire app is here
│ ├── standalone/ ← If using output: 'standalone'
│ │ └── server.js ← Optimized server entry
│ ├── server/
│ └── static/
└── ...
22.2.3 Deployment
Option 1: Standard deployment
# Copy entire project to server, then:
npm run build
npm run start # Runs on port 3000
Option 2: Standalone mode (smaller, optimized)
# After build, copy only:
# - .next/standalone/
# - .next/static/
# - public/
# Then run:
node .next/standalone/server.js
22.3 Visual Comparison
STATIC EXPORT (output: 'export')
================================
Source Code → npm run build → out/ folder
↓
Pure HTML/CSS/JS
↓
┌───────────┴───────────┐
↓ ↓
Netlify/Firebase CDN/Static Host
(Like Flutter web!)
SERVER-SIDE (default or 'standalone')
====================================
Source Code → npm run build → .next/ folder
↓
Server-side code + Client JS
↓
Node.js Server
↓
┌───────────┴────────────┐
↓ ↓
Vercel/Railway/AWS Docker Container
22.4 Feature Comparison Table
Feature | Static Export | Server-Side |
---|---|---|
Hosting | Any static host (Netlify, Firebase) | Requires Node.js server |
Cost | Usually free/cheap | Higher (server costs) |
Build Output | out/ folder (HTML files) |
.next/ folder (server code) |
Server-Side Rendering (SSR) | ❌ No | ✅ Yes |
Incremental Static Regeneration (ISR) | ❌ No | ✅ Yes |
API Routes | ❌ No | ✅ Yes |
Dynamic Routes | Limited (must pregenerate) | ✅ Full support |
Image Optimization | ❌ Must disable | ✅ Yes |
revalidate | ❌ No | ✅ Yes |
Similar to | Flutter web build | Flutter with backend |
22.5 When to Use Which?
22.5.1 Use Static Export if:
- ✅ Content doesn’t change often (like portfolio, docs)
- ✅ You want to deploy to Firebase Hosting/Netlify (your current setup!)
- ✅ You want lowest cost
- ✅ All pages can be pre-rendered at build time
- ✅ No need for API routes (use external API instead)
22.5.2 Use Server-Side if:
- ✅ Need real-time data
- ✅ User-specific content (dashboards, admin panels)
- ✅ Need API routes in Next.js
- ✅ Want image optimization
- ✅ Need ISR (update pages without rebuilding)
22.6 Example: Converting to Static Export
If you have an existing Next.js app and want static export:
1. Update next.config.js:
.exports = {
moduleoutput: 'export',
images: {
unoptimized: true, // Required!
} }
2. Remove server-only features:
// ❌ Remove these from pages:
export async function getServerSideProps() { ... }
// ✅ Keep these:
export async function getStaticProps() { ... }
export async function getStaticPaths() { ... }
// ❌ Remove API routes:
// pages/api/* or app/api/*
3. Build:
npm run build # Creates out/ folder
4. Deploy:
firebase deploy
22.7 Quick Test
Want to see which mode you’re in?
# After npm run build, check:
ls out/ # If exists → static export
ls .next/standalone/ # If exists → standalone server mode
Given your background with Firebase Hosting and Netlify, static export might be your go-to for many projects, similar to how you’d deploy Flutter web apps!