Next.js Static Generation vs SSR: When to Use Each
Next.js is powerful precisely because it doesn't force you into a single rendering strategy. You can mix static generation, server-side rendering, and client-side rendering at the page level. That flexibility is a strength, but it also creates a real decision to make for every route in your application. Here's a clear framework for making that call.
The Four Rendering Strategies in Next.js
Before comparing static vs SSR, it helps to know all the options:
- 1Static Site Generation (SSG) — HTML is generated at build time. Every visitor gets the same pre-built file.
- 2Server-Side Rendering (SSR) — HTML is generated on the server on every request.
- 3Incremental Static Regeneration (ISR) — Static pages that regenerate in the background after a configurable time interval.
- 4Client-Side Rendering (CSR) — The server sends a minimal HTML shell; JavaScript fetches and renders data in the browser.
Most production Next.js apps use a combination of all four.
Static Generation (SSG): The Default Choice
Static generation is the right default for any page where the content is the same for every user and doesn't change every few seconds.
In the Pages Router, you signal static generation by exporting getStaticProps. In the App Router, any Server Component that doesn't use request-time data (no cookies, no headers) is statically generated by default.
SSG is ideal for:
- Marketing and landing pages
- Blog posts and documentation
- Product catalog pages
- About, pricing, and FAQ pages
The performance benefits are significant. Statically generated pages are cached at the CDN edge, delivering sub-100ms TTFB globally. They're also trivially scalable — a CDN handles any traffic volume.
Server-Side Rendering (SSR): When You Need Request-Time Data
SSR runs your data-fetching logic on the server on every request. In the Pages Router, you export getServerSideProps. In the App Router, you use cookies or headers in a Server Component, which opts it out of static caching.
SSR is appropriate when:
- Page content depends on the incoming request (authentication cookies, geolocation headers)
- You must show real-time data that can't be stale for even a few seconds
- You need to compute access control server-side before rendering
- SEO requires personalized content to be in the initial HTML (e.g., localized pricing)
The cost is latency. Every SSR page requires a round-trip to your origin server, database queries, and template execution. TTFB rises to 200–500ms+ depending on your server location and query complexity.
Incremental Static Regeneration (ISR): The Middle Ground
ISR is often the best of both worlds. You define a revalidate interval (e.g., 60 seconds). Next.js serves the cached static version immediately, then regenerates it in the background after the interval expires. The next request after regeneration gets the fresh version.
ISR is ideal for:
- E-commerce product pages (prices and inventory update periodically)
- News articles (content rarely changes after publish)
- Dashboard overviews where slight staleness is acceptable
ISR gives you CDN-speed page loads while keeping content reasonably fresh without full SSR overhead.
Client-Side Rendering (CSR): For Authenticated, Personalized UI
CSR loads a static shell and fetches data from APIs in the browser using useEffect, SWR, or React Query. The initial HTML is fast (it's static), but meaningful content appears only after the API call resolves.
CSR is appropriate for:
- User dashboards with private data
- Any page behind a login wall where SEO doesn't matter
- Real-time feeds and live updating data
Decision Framework
Ask yourself these questions for each page:
- 1Is the content identical for every visitor? → SSG
- 2Does the content change, but not more than once every minute? → ISR
- 3Is the content personalized per user or dependent on the request? → SSR or CSR
- 4Is the page behind a login wall and SEO doesn't matter? → CSR
Deploying Next.js Static Exports on PandaStack
If your Next.js app uses only SSG (no SSR, no API routes that require a Node.js server), you can export it as a fully static site using next build with output: 'export' in your Next.js config. The output directory (out by default) can then be deployed as a static site.
On PandaStack, add a pandastack.json with your buildCommand set to npm run build and outputDir set to out. PandaStack will auto-deploy from GitHub on every push. For apps that need SSR, you can deploy the Next.js server as a Docker container on PandaStack.
Learn more at [docs.pandastack.io](https://docs.pandastack.io) and get started at [dashboard.pandastack.io](https://dashboard.pandastack.io).