TL;DR: Server-side rendering (SSR) means the server builds your page's HTML before sending it to the browser, so content loads instantly and search engines can read it. AI generates Next.js because it uses SSR by default. The "use client" line marks components that need to run in the browser for interactive features like buttons and forms.

Why AI Coders Need This

If you've been building with AI for more than a week, you've noticed something: your AI loves Next.js. Ask it to build a dashboard, a blog, a SaaS app, a portfolio — doesn't matter. Claude Code, Cursor, Windsurf, they all reach for the same thing:

npx create-next-app@latest my-project

There's a reason for this, and it's not because AI is lazy. Next.js is the most popular React framework on the planet — over 7 million weekly downloads on npm, used by Netflix, TikTok, and the Washington Post. It dominates AI training data. When your AI needs to build something that works out of the box with routing, backend APIs, and good SEO, Next.js is the obvious answer.

But here's the thing that trips people up: Next.js uses server-side rendering by default. That changes everything about how your app works. Files run on the server unless you tell them not to. Components that seem fine in development break in production. You see cryptic errors about "hydration" that make zero sense.

And then there's that line your AI keeps putting at the top of files:

"use client"

If you don't understand what that means — and more importantly, when it should be there — you'll spend hours stuck in debugging loops where the AI keeps generating code that creates new errors.

You don't need a computer science degree to understand SSR. You need to know what it does, why your AI chose it, and what to do when it causes problems. That's this article.

What It Does: SSR vs CSR Explained Simply

There are two fundamental ways to build a web page. Understanding the difference will save you hours of confusion.

Client-Side Rendering (CSR) — The Old React Way

Think of client-side rendering like ordering a piece of furniture that ships as a flat-pack. You get a box of parts (that's the JavaScript code), and your browser has to assemble it into a finished page.

Here's what happens step by step:

  1. Your browser requests a page
  2. The server sends back a nearly empty HTML file — just a skeleton with a <div id="root"></div>
  3. Your browser downloads the JavaScript bundle
  4. The JavaScript runs and builds the entire page inside that empty div
  5. Now you can finally see and interact with the content

This is how plain React works. If you've ever used create-react-app or built a React project without Next.js, this is what was happening. The problem? Steps 3 and 4 take time. Your visitor sees a blank white screen (or a loading spinner) until all that JavaScript downloads and runs.

For Google, it's even worse. When a search engine crawler visits your page, it often sees that empty <div id="root"></div> and nothing else. Your content is invisible to search engines unless they run your JavaScript — which they sometimes do, but not reliably.

Server-Side Rendering (SSR) — The Next.js Way

Server-side rendering is like ordering that same piece of furniture, but fully assembled and delivered ready to use. The factory (the server) puts everything together before shipping it to you.

Here's the SSR flow:

  1. Your browser requests a page
  2. The server runs the React components and generates complete HTML
  3. The server sends that fully-built HTML to the browser
  4. Your browser displays the content immediately — no blank screen
  5. JavaScript downloads in the background and makes the page interactive (this is called hydration)

The key difference: with SSR, the visitor sees content right away. With CSR, they wait for JavaScript to build the page. Google sees real content with SSR, and sees an empty page with CSR.

That's why AI picks Next.js. It's giving you the better approach by default.

The Construction Analogy: CSR is like shipping building materials to a job site and having the crew assemble everything on-location. SSR is like building a wall in the factory and trucking the finished wall panel to the site. The end result is the same wall, but the factory-built one goes up faster because the heavy work was done before it arrived.

What the DOM Has to Do with It

When we say the server "builds the HTML," that HTML becomes the DOM — the live structure of your page that the browser can display and interact with. With CSR, JavaScript has to build the entire DOM from scratch in the browser. With SSR, the DOM arrives mostly ready — JavaScript just needs to attach event handlers to make buttons clickable and forms submittable. That "attaching" step is hydration.

The Real Scenario: AI Generates Next.js with "use client"

Let's walk through exactly what happens when you ask your AI to build something. You open Claude Code and type:

Prompt You Would Type

Build me a task management app with a dashboard
that shows tasks, lets me add new ones, and has
a sidebar for filtering by category.

Your AI generates a Next.js project. You look at the files and see something like this:

app/
  layout.tsx          ← No "use client" — runs on the server
  page.tsx            ← No "use client" — runs on the server
  globals.css
  components/
    Sidebar.tsx       ← Has "use client" at the top
    TaskList.tsx      ← Has "use client" at the top
    AddTaskForm.tsx   ← Has "use client" at the top
    TaskCard.tsx      ← No "use client" — runs on the server

Some files have "use client" at the top. Some don't. This is the most important distinction in modern Next.js, and here's what it means:

Files WITHOUT "use client" = Server Components

These run on the server. They can:

  • Fetch data directly from a database
  • Read files from the server's file system
  • Use secret API keys safely (they never reach the browser)
  • Generate HTML that's sent to the browser ready-to-display

They cannot:

  • Respond to clicks, hovers, or keyboard events
  • Use useState or useEffect
  • Access browser features like localStorage or window
  • Do anything interactive

Files WITH "use client" = Client Components

These run in the browser. They can:

  • Handle clicks, form submissions, keyboard input
  • Use React hooks like useState, useEffect, useRef
  • Access browser APIs (window, localStorage, navigator)
  • Show/hide content, animate, update in real time

They cannot:

  • Safely hold secret keys or database passwords
  • Directly query a database (the code runs in the user's browser)

Why AI Mixes Both

Look at that file structure again. The AI made layout.tsx and page.tsx server components because they just arrange content on the page — no interactivity needed. But Sidebar.tsx needs to handle click events for filtering, AddTaskForm.tsx needs form input handling, and TaskList.tsx needs to update when you add a task. Those require the browser. So the AI adds "use client".

The AI is making a smart architectural decision here. It's keeping data-fetching and layout on the server (fast, secure, SEO-friendly) while pushing only the interactive parts to the browser. You don't need to plan this yourself — just understand why the AI did it.

Think of it this way: Server components are the structure of a building — the walls, floor, roof. They're built at the factory and arrive ready. Client components are the electrical and plumbing — the parts that respond when you flip a switch or turn a faucet. You need both, but they're built differently.

What "use client" Actually Looks Like in Code

It's always the very first line of the file, before any imports:

"use client"

import { useState } from "react"

export default function AddTaskForm() {
  const [task, setTask] = useState("")

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={task}
        onChange={(e) => setTask(e.target.value)}
        placeholder="Add a new task..."
      />
      <button type="submit">Add</button>
    </form>
  )
}

That "use client" at the top tells Next.js: "This component needs the browser. Don't try to run it on the server." Without it, you'd get an error because useState and onChange only work in the browser.

When SSR Matters and When It Doesn't

Not every project needs SSR. Here's an honest breakdown:

SSR Matters When:

You need Google to find your content. If you're building a blog, a marketing site, an e-commerce store, a documentation site, or anything where search engine traffic is important — SSR is critical. Google's crawler will see your fully-rendered content instead of an empty page. This is probably the #1 reason your AI chooses Next.js.

First-page load speed matters. If your app's first impression is a blank screen with a loading spinner, users bounce. SSR sends ready-to-display HTML immediately. This is especially important on mobile devices with slow connections.

You're sharing links on social media. When someone pastes your link into Twitter, Slack, or Discord, those platforms read the HTML to generate a preview card. CSR pages often show blank previews because there's no content in the HTML. SSR pages show the actual title, description, and image.

Accessibility and progressive enhancement. SSR pages work even if JavaScript fails to load. Screen readers get real content. Users with older browsers or JavaScript disabled still see your page.

SSR Doesn't Matter Much When:

You're building a dashboard or internal tool. Nobody is Googling your company's internal admin panel. Users are logged in already. A loading spinner on first load is totally fine. CSR (plain React) would work great here.

The app lives behind a login. Search engines can't crawl authenticated pages anyway. Social sharing previews don't apply. If your entire app requires authentication, SSR adds complexity without much benefit.

You're building a real-time app. Chat apps, collaborative editors, live dashboards — these are almost entirely client-side. The initial page load matters less than the constant stream of updates happening in the browser.

So Should You Even Care?

Honest answer: let the AI handle it most of the time. Your AI chose Next.js and SSR for good reasons. It's setting up the architecture correctly. You should care about SSR exactly enough to:

  1. Understand why "use client" is there (so you don't remove it by accident)
  2. Know what hydration errors mean (so you can fix them)
  3. Recognize when you're overcomplicating things (maybe your internal tool doesn't need Next.js at all)

That's it. You don't need to architect SSR strategies. You need to understand what the AI built and debug it when it breaks.

What Can Go Wrong

SSR introduces a category of bugs that plain React apps never have. Here are the ones you'll actually hit:

1. Hydration Errors

This is the big one. Remember, SSR works in two steps: the server generates HTML, then the browser's JavaScript "hydrates" it (attaches event handlers and makes it interactive). If the HTML the server generated doesn't exactly match what the browser's JavaScript tries to create, React throws a hydration error.

You'll see something like:

Error: Hydration failed because the initial UI does not
match what was rendered on the server.

Warning: Expected server HTML to contain a matching <div>
in <div>.

Common causes:

  • Using Date.now() or Math.random() during rendering (server and client get different values)
  • Checking window.innerWidth to show/hide content (server doesn't have a window)
  • Browser extensions injecting extra HTML into your page
  • Using localStorage values to set initial state

2. "window is not defined"

This is the second most common SSR error. It means you tried to use a browser-only feature in a server component. The server doesn't have a window, document, or localStorage — those only exist in the browser.

ReferenceError: window is not defined

Common causes:

  • Importing a library that uses window internally (many UI libraries do this)
  • Trying to read window.location or document.cookie in a server component
  • Third-party scripts that assume they're running in a browser

3. Missing "use client" Directive

You add a click handler or useState to a component, but forget to add "use client" at the top. Next.js tries to run it on the server and throws an error:

Error: useState only works in Client Components. Add the
"use client" directive at the top of the file to use it.

The fix is straightforward — add "use client" as the first line. But AI sometimes forgets this, especially when it's modifying an existing server component to add interactivity.

4. Content Flash (FOUC)

Sometimes you see the page's content flash or shift when it first loads. The server sends HTML with one layout, then the client JavaScript adjusts it — maybe because CSS-in-JS libraries need to recalculate styles, or because a component renders differently once it detects the actual screen size.

This isn't technically an error, but it looks unprofessional. Your AI usually handles this well, but if you see content jumping around on page load, SSR/hydration mismatch is likely the cause.

5. Making Everything "use client"

When people hit SSR errors, a common instinct is to slap "use client" on every file to make the errors go away. It works — but you lose every benefit of SSR. Your pages become blank for search engines, load times increase, and you're essentially running a plain React app with extra complexity. If every component is a client component, you'd be better off not using Next.js at all.

How to Debug SSR Issues

When SSR breaks, here's your playbook. These are prompts you can actually paste into your AI tool:

For Hydration Errors

Prompt for Your AI

I'm getting this hydration error in my Next.js app:
[paste the full error message]

The component is [paste the component code].

Find what's different between the server render and
the client render. Don't just suppress the error —
fix the root cause.

The key phrase is "don't just suppress the error." AI will sometimes wrap things in suppressHydrationWarning to make the error disappear without actually fixing it. That's a bandaid, not a fix.

For "window is not defined"

Prompt for Your AI

I'm getting "window is not defined" in this component:
[paste the component]

This is a Next.js app using the App Router. Either:
1. Move browser-only code into useEffect
2. Add a typeof window check
3. Make this a client component with "use client"

Pick the best approach for this specific case and
explain why.

For "use client" Confusion

Prompt for Your AI

Review my Next.js app's component tree and tell me
which components need "use client" and which should
stay as server components. Here's my file structure:
[paste your app/ directory tree]

For each component, explain WHY it should be server
or client. I want to understand the reasoning.

General Debugging Tips

  • Check the terminal, not just the browser. SSR errors often appear in the terminal where you ran npm run dev, not in the browser console. Always check both.
  • Compare dev vs production. Some SSR issues only appear in production. If something works in npm run dev but breaks in npm run build && npm run start, it's almost certainly an SSR problem.
  • View page source. Right-click your page and select "View Page Source." If you see your actual content in the HTML, SSR is working. If you see an empty <div>, it's not.
  • Disable JavaScript to test. In Chrome DevTools, press Cmd+Shift+P (or Ctrl+Shift+P) and type "Disable JavaScript." Reload the page. What you see is what Google sees with SSR. If the page is blank, your SSR isn't working correctly.

When to Tell Your AI to Skip SSR Entirely

Sometimes the right move is to tell your AI not to use Next.js at all. Here's the prompt:

Prompt for Your AI

Build this as a plain React app with Vite — no Next.js,
no SSR. This is an internal tool behind authentication
and doesn't need SEO or server rendering.

Use this when:

  • Your entire app is behind a login
  • You don't need search engines to index it
  • The app is purely interactive (dashboards, admin panels, data visualization tools)
  • You want simpler deployment (static files on any hosting)
  • You're tired of hydration errors and the project doesn't benefit from SSR anyway

There's no shame in using plain React with Vite. It's simpler, has fewer gotchas, and deploys to Vercel, Netlify, or any static hosting without a server. Next.js adds real value, but only when you need what it provides.

Quick Reference: SSR, SSG, and ISR

You'll see these abbreviations in Next.js documentation and AI-generated code. Here's what each one means:

SSR (Server-Side Rendering) — The server builds the page fresh every time someone requests it. Good for pages with data that changes constantly, like a news feed or a dashboard. The server does work on every single page load.

SSG (Static Site Generation) — The server builds the page once at build time and reuses that HTML for every visitor. Good for pages that rarely change, like blog posts or documentation. Extremely fast because there's no server work per request.

ISR (Incremental Static Regeneration) — A hybrid. The page is built at build time like SSG, but the server rebuilds it in the background at intervals you set. Good for pages that change occasionally, like product listings. You get SSG speed with reasonably fresh data.

In the Next.js App Router, your AI controls this through how it fetches data. You generally don't need to configure it yourself — but knowing these terms helps you understand what the AI built and why.

What AI Gets Wrong About SSR

AI tools are good at SSR, but they make predictable mistakes:

  • Mixing up App Router and Pages Router patterns. Next.js has two routing systems. The AI's training data includes both, and it sometimes generates Pages Router patterns (getServerSideProps, getStaticProps) in an App Router project. If you see those in an app/ directory, tell the AI: "This is an App Router project. Use server components and async functions, not getServerSideProps."
  • Putting "use client" too high or too low. Sometimes AI makes an entire page a client component when only one small part needs interactivity. Other times it forgets "use client" on a component that handles clicks. Both cause problems — the first kills SEO, the second causes runtime errors.
  • Using suppressHydrationWarning as a fix. This hides the error message without fixing the underlying mismatch. It's acceptable for things like timestamps that will always differ, but the AI sometimes uses it to paper over real bugs.
  • Importing browser-only libraries in server components. Libraries like chart.js, mapbox-gl, or UI libraries that access window internally will crash if imported in a server component. The AI should use dynamic imports with { ssr: false }, but it doesn't always remember.

Frequently Asked Questions

What is server-side rendering in simple terms?

Server-side rendering means the server builds your page's complete HTML before sending it to the browser. Instead of your browser downloading an empty page and running JavaScript to fill it in, SSR sends a fully assembled page that displays immediately. It's like getting a pre-built bookshelf delivered to your door versus getting a box of parts with assembly instructions.

Why does AI always generate Next.js projects?

AI tools generate Next.js because it's the most popular React framework in their training data, with over 7 million weekly npm downloads. Next.js handles frontend and backend in one project, uses server-side rendering by default for better SEO and performance, and deploys easily to platforms like Vercel. It's the path of least resistance for AI to give you a complete working app.

What does "use client" mean at the top of a file?

"use client" is a directive that tells Next.js this component needs to run in the browser, not on the server. You need it when a component uses interactive features like useState, useEffect, onClick handlers, or browser APIs like localStorage. Without it, Next.js assumes the component is a server component — and server components can't handle clicks, form inputs, or anything interactive.

Do I need to understand SSR to vibe code?

You don't need to understand how SSR works under the hood, but you need to know it exists and what it affects. Most SSR problems show up as hydration errors, content flashing, or components that work in development but break in production. Knowing the basics — server components vs client components, when to add "use client", and what hydration errors mean — saves you hours of frustrating debugging.

What is a hydration error and how do I fix it?

A hydration error happens when the HTML the server generated doesn't match what the browser's JavaScript tries to create. Common causes include using browser-only values like window.innerWidth during rendering, dates or random numbers that produce different values on server and client, and browser extensions modifying the page. Fix it by wrapping browser-dependent code in useEffect or behind a typeof window !== "undefined" check, and adding "use client" to components that need browser APIs.

What to Learn Next

Now that you understand SSR and why your AI keeps reaching for Next.js, here's where to go from here:

  • What Is Next.js? — The full deep-dive into Next.js's project structure, App Router, API routes, and common AI mistakes.
  • What Is React? — Understand the library underneath Next.js — components, props, state, and how the AI uses them.
  • What Is the DOM? — The browser's page structure that SSR generates and hydration connects to. Understanding the DOM makes hydration errors less mysterious.
  • What Is Vercel? — The platform built by the creators of Next.js. Where most AI-generated Next.js apps get deployed.

The pattern here is straightforward: your AI generates Next.js with SSR because it's the best default choice for most projects. Understanding the boundary between server and client components — and knowing what "use client" means — puts you in control of the code your AI generates. You don't need to architect SSR yourself. You need to understand what your AI built and why.