Suggest an editImprove this articleRefine the answer for “What is Next.js and why use it”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Next.js** is a React framework that adds server-side rendering, file-based routing, and built-in optimization to React. ```javascript // Next.js Server Component - data fetched on server, full HTML sent to browser export default async function BlogPost({ params }) { const post = await fetch(`https://api.example.com/posts/${params.slug}`) .then(r => r.json()); return <article><h1>{post.title}</h1></article>; } // Google and users both see real content on the first load ``` **Key point:** React renders in the browser after JS loads. Next.js renders on the server first, so search engines see real HTML immediately and users see pages faster.Shown above the full answer for quick recall.Answer (EN)Image**Next.js** is a React framework that adds server-side rendering, file-based routing, and built-in optimization so you can skip configuring all of that yourself. ## Theory ### TL;DR - React renders in the browser after JS loads; Next.js renders on the server first, sends HTML, then hydrates with React - File structure inside `app/` becomes routes automatically, no React Router needed - SSR, SSG, ISR, and CSR are all available per page - Use Next.js for blogs, e-commerce, marketing sites where SEO matters; use plain React for dashboards and internal tools ### Quick example The difference shows up immediately in how routing works: ```javascript // Plain React - you wire up routing manually import { BrowserRouter, Routes, Route } from 'react-router-dom'; export default function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </BrowserRouter> ); } // Next.js - file structure is the routing // app/page.js -> / // app/about/page.js -> /about // No Router component. No configuration. ``` No setup. The file exists, the route exists. ### Key difference React is a UI library. It renders components in the browser after JavaScript loads, which means search engines see an empty `<div>` until JS executes. Next.js flips this: the server runs your component code, generates real HTML, and sends it to the browser. The user sees content immediately. Then React loads in the background and hydrates the page, attaching event listeners. Same components, same hooks, but the first paint happens on the server, not in the browser. ### Rendering strategies Next.js gives you four rendering modes, and you pick per page: - **SSR** - server renders on every request. Good for personalized content or data that changes frequently. - **SSG** - page is built once at deploy time, served from CDN. Fastest option for content that rarely changes. - **ISR** - static page that regenerates in the background on a schedule. Gets you CDN speed with fresher data. - **CSR** - regular client-side React. Use this when a page needs no SEO and is fully interactive. ```javascript // SSR: cache: 'no-store' forces a fresh server render on each request export default async function Page() { const data = await fetch('https://api.example.com/posts', { cache: 'no-store' }); const posts = await data.json(); return <PostList posts={posts} />; } // ISR: regenerates every hour, serves cached HTML in between export default async function Page() { const data = await fetch('https://api.example.com/posts', { next: { revalidate: 3600 } }); const posts = await data.json(); return <PostList posts={posts} />; } ``` ### When to use **Next.js makes sense when:** - SEO matters: blogs, e-commerce, marketing pages - First load speed is a priority - You need server-side auth or personalization - You want routing, API routes, and image optimization already wired up **Plain React makes more sense when:** - Building an admin dashboard or internal tool that Google never crawls - All content is generated client-side (think Figma or a real-time editor) - You are prototyping and want the simplest possible setup ### Comparison table | Aspect | React (SPA) | Next.js | |--------|-------------|----------| | Routing | Manual (react-router) | File-based, automatic | | Initial HTML | Empty `<div>` | Full page content | | SEO | Poor without extra setup | Good out of the box | | First load | Waits for JS | HTML + CSS first | | Data fetching | `useEffect` on client | Server Components, fetch on server | | API | None | Route Handlers built in | | Deployment | Static hosting | Node.js server or serverless | | Good for | Dashboards, internal tools | Blogs, stores, marketing sites | ### How it works internally When you request a Next.js page, the server runs your component and produces HTML. That HTML goes to the browser right away. The user sees content before any JavaScript runs. Then React loads and hydrates the page, connecting event listeners and making it interactive. For static pages (SSG/ISR), this HTML is pre-generated and served from a CDN. The server is not involved on every request, so static pages load faster than SSR ones. Server Components are the default in the App Router (Next.js 13+). They run only on the server, so you can read from a database directly without exposing credentials. When a component needs interactivity like `useState` or `onClick`, add `'use client'` at the top of the file. ```javascript // Server Component (default) - runs on server only export default async function UsersPage() { const users = await db.user.findMany(); // direct DB access, no credentials leak return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); } // Client Component - needs 'use client' for hooks and event handlers 'use client'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Clicks: {count} </button> ); } ``` ### Common mistakes **1. Using `useEffect` to fetch data instead of async server components** The whole point of Server Components is that data fetching happens on the server. Reach for `useEffect` and you are back to client-side rendering: empty HTML ships first, data loads after JS runs. ```javascript // Wrong - defeats server rendering export default function Page() { const [data, setData] = useState(null); useEffect(() => { fetch('/api/data').then(r => r.json()).then(setData); }, []); return <div>{data?.name}</div>; // browser gets empty HTML first } // Right - fetch directly in the async component export default async function Page() { const data = await fetch('https://api.example.com/data').then(r => r.json()); return <div>{data.name}</div>; // server sends full HTML } ``` **2. Using hooks in a Server Component** Server Components run on the server. `useState`, `useContext`, event handlers - none of these work there. The fix is `'use client'` at the top of the file. **3. Hydration mismatch** If the server renders different HTML than the client, React cannot attach event listeners correctly. A common cause is rendering `new Date()` directly in the component. ```javascript // Wrong - server renders '10:20:18 PM', client renders '10:20:25 PM' export default function Time() { return <div>{new Date().toLocaleTimeString()}</div>; } // Right - render the time only on the client with useEffect 'use client'; import { useEffect, useState } from 'react'; export default function Time() { const [time, setTime] = useState(''); useEffect(() => setTime(new Date().toLocaleTimeString()), []); return <div>{time}</div>; } ``` **4. Putting secret API keys in Server Component files** Server Components run on the server, but the code is included in the React Server Component payload that goes to the browser. Secret keys end up visible in network requests. Keep them in `.env.local` and use them only in API routes or Server Actions, not in component files. **5. Rebuilding the entire site on every deploy instead of using ISR** 10,000 product pages means a full rebuild takes minutes and users see stale content during the build. Use `revalidate`: first request generates and caches HTML, all requests in that window serve from cache instantly, after the interval Next.js regenerates in the background while the old page still serves. ### Real-world usage - TikTok, Hulu, Nike: marketing sites and e-commerce where SEO matters - Stripe, GitHub: documentation sites - Shopify Hydrogen: commerce framework built on Next.js - Notion, Linear: Next.js for public pages, plain React for internal tools - Vercel: their entire platform runs on Next.js, Server Components power the dashboard ### Follow-up questions **Q:** What is the difference between Server Components and SSR? **A:** SSR is a deployment pattern where React renders HTML on a Node.js server on each request. Server Components are a React 18 feature that run on the server and stream JSX to the client. Next.js uses both: Server Components by default, SSR for dynamic pages. **Q:** If Next.js renders on the server, how does it handle real-time updates? **A:** Server Components render once and produce static HTML. For real-time data, use Client Components with `useEffect` or WebSockets. For occasional refreshes, Server Actions with `revalidatePath()` can trigger a fresh render for specific pages. **Q:** Why would you pick SSG over SSR? **A:** SSG pre-renders at build time and serves from a CDN - instant, no per-request server cost. SSR renders on every request, which is slower and more expensive. Use SSG for content that changes rarely (blog posts, product pages). Use SSR for personalized content or data that changes by the minute. **Q:** What happens when a Server Component has a slow database query? **A:** The page waits until the query completes before sending any HTML to the browser. Wrap slow components in `<Suspense>` to show a loading state while the rest of the page renders immediately. The slow component streams in once the data is ready. **Q:** (Senior level) How would you structure a site where some pages are static, some are SSR, and some are CSR? **A:** Use `revalidate` (ISR) for mostly-static pages like product listings. Use SSR (`cache: 'no-store'`) for personalized or auth-gated content. Use Client Components for fully interactive sections. Static is fastest but can be stale. SSR is always fresh but adds server latency. CSR is interactive but loses SEO. The right split depends on how often content changes and whether search engines need to index it. ## Examples ### Server-side data fetching in a blog post page ```javascript // app/blog/[slug]/page.js // Runs on the server. params.slug comes from the URL segment. export default async function BlogPost({ params }) { const post = await fetch( `https://api.example.com/posts/${params.slug}` ).then(r => r.json()); // Server generates this HTML fully populated before sending to browser. // Google crawls the full post content on first request. return ( <article> <h1>{post.title}</h1> <p>{post.content}</p> </article> ); } ``` URL `/blog/next-js-guide` sets `params.slug` to `"next-js-guide"`. The fetch runs on the server. The HTML that reaches the browser already has the title and content in it, not empty placeholders. ### ISR for a product page with 10,000 products ```javascript // app/products/[id]/page.js export const revalidate = 3600; // regenerate every hour export default async function Product({ params }) { const product = await fetch( `https://api.example.com/products/${params.id}`, { next: { revalidate: 3600 } } ).then(r => r.json()); return ( <div> <h1>{product.name}</h1> <p>${product.price}</p> </div> ); } ``` First request generates and caches HTML. All requests in the next hour serve from cache instantly. After the hour, Next.js regenerates in the background while the old page still serves. Price changes appear within the hour without touching the deploy pipeline. ### Mixing Server and Client Components ```javascript // app/dashboard/page.js - Server Component fetches data import StatsChart from './StatsChart'; export default async function Dashboard() { const stats = await fetch('https://api.example.com/stats', { cache: 'no-store' }).then(r => r.json()); // Pass data to a Client Component that handles interactivity return ( <main> <h1>Dashboard</h1> <StatsChart data={stats} /> </main> ); } ``` ```javascript // app/dashboard/StatsChart.js - Client Component handles state 'use client'; import { useState } from 'react'; export default function StatsChart({ data }) { const [view, setView] = useState('weekly'); return ( <div> <button onClick={() => setView('weekly')}>Weekly</button> <button onClick={() => setView('monthly')}>Monthly</button> <p>Showing {view} data: {data[view]}</p> </div> ); } ``` The server does the expensive data fetch, the client handles state changes without extra network requests. I have used this split on production dashboards - the initial page load stays fast because no JS needs to run before the user sees their data.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.