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
  // }
}

module.exports = nextConfig

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
}

module.exports = nextConfig

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:

module.exports = {
  output: '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!