ScreenshotNeo

BlogGuides

What Is Next.js? A Guide to the React Framework

Next.js is a React framework for building web applications. Learn how its routers, Server and Client Components, data fetching, and deployment options fit together.

By the ScreenshotNeo team1 October 20269 min read

Next.js is a React framework for building web applications. React gives you components; Next.js adds conventions and capabilities for organizing routes, rendering UI on the server or in the browser, fetching data, and deploying an application. Its recommended App Router is file-system based and uses React features such as Server Components, Suspense, and Server Functions. Next.js App Router documentation

Use Next.js when you want an application framework around React rather than assembling routing and server behavior yourself. If you are learning React, learn its components, props, state, and rendering model alongside Next.js; prior React experience helps, but the Next.js documentation teaches the framework from the beginning.

1. What Next.js adds to React

React is a JavaScript library for building user interfaces from components. Next.js is a framework built around React. It supplies a structure for routes and pages, shared layouts, server and client rendering, data access patterns, and production deployment.

Question Short answer
Is Next.js a framework or a library? A React framework.
Is Next.js the same as React? No. Next.js uses React and adds application-level conventions and features.
Does Next.js require server rendering? No single rendering approach applies to every component or route. App Router applications can combine Server and Client Components, and deployment options vary.
Does Next.js only work with a particular hosting provider? No. The documented options include a Node.js server, Docker, static export, and platform adapters.

These are capabilities, not a guarantee of faster pages or better search rankings. Results depend on what an application renders, how it fetches and serves data, and how it is deployed.

2. The App Router: folders, pages, and layouts

The App Router uses folders and special files to map application structure to routes. A page file provides the UI for a route. A layout provides shared UI around pages; layouts can preserve state and remain interactive during navigation. Layouts and Pages documentation

For example, app/about/page.tsx corresponds to /about. A root app/layout.tsx wraps routes beneath it.

// app/layout.tsx
import type { ReactNode } from 'react';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <header>Example app</header>
        {children}
      </body>
    </html>
  );
}

// app/page.tsx
export default function HomePage() {
  return <main><h1>Welcome</h1><p>A Next.js page.</p></main>;
}

// app/about/page.tsx
export default function AboutPage() {
  return <main><h1>About</h1></main>;
}

This example uses TypeScript and JSX. The same route convention works with JavaScript files such as page.js and layout.js. Route groups, dynamic segments, loading and error files, and other special conventions support larger applications; see the App Router reference for the complete file conventions.

3. Server Components and Client Components

In the App Router, pages and layouts are Server Components by default. Server Components can read data and render on the server. Add a Client Component where browser-side state, event handlers, lifecycle behavior, or browser APIs such as window are needed. A route can combine both kinds. Server and Client Components documentation

Use the "use client" directive at the top of a module to mark a client boundary. Keep that boundary around the interactive part that needs it rather than treating the whole app as client-only.

// app/counter.tsx
"use client";

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

// app/page.tsx
import Counter from './counter';

export default function HomePage() {
  return <main><h1>Server-rendered page</h1><Counter /></main>;
}

The boundary has practical consequences: browser-only APIs belong in client-side code, and values passed between server and client need to be suitable for that boundary. Keep secrets and privileged data access on the server. Authenticate and authorize database access; choosing a Server Component does not itself secure a query.

4. Fetching data and showing slow sections

Server Components can perform asynchronous I/O, including the Fetch API or ORM/database access. The current fetching guide says identical fetch requests in a React component tree are memoized by default, while fetch requests are not cached by default and can block rendering until they finish. Defaults can change between framework releases, so check the guide for the version you use. Fetching Data documentation

// app/posts/page.tsx
async function getPosts() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  if (!response.ok) throw new Error(`Request failed: ${response.status}`);
  return response.json() as Promise<{ id: number; title: string }[]>;
}

export default async function PostsPage() {
  const posts = await getPosts();
  return (
    <main>
      <h1>Posts</h1>
      <ul>{posts.slice(0, 10).map(post => <li key={post.id}>{post.title}</li>)}</ul>
    </main>
  );
}

For slower or uncached work, a route’s loading.js or React <Suspense> boundary can let the application stream a fallback and reveal a section when its data is ready. This improves how the page can respond while work is pending; it does not make the upstream service faster.

Data caching and rendering behavior are version-sensitive. Choose caching and revalidation behavior deliberately for your Next.js version, especially for personalized or frequently changing data. Never expose credentials in client code, and authorize every request to protected records.

5. App Router or Pages Router?

The Pages Router remains supported. The Next.js documentation recommends the App Router for projects that want React’s latest features. That recommendation does not mean an existing Pages Router project must migrate immediately. Pages Router documentation

Situation Practical choice
Starting a project and want the current documented React features Start with the App Router.
Maintaining an established Pages Router application Continue using it where it meets your needs; plan a migration when the benefits justify the work.
Considering a migration Assess route by route, test data fetching and rendering behavior, and account for changes to app structure and APIs.

Both use file-system routing, but the App Router centers on Server Components, Suspense, and Server Functions. Migration effort depends on the existing application’s structure and features; the documentation recommendation is not a claim that every project has the same migration cost.

6. Create and run a Next.js application

As listed in the installation guide updated March 16, 2026, the minimum Node.js version is 20.9. Supported operating systems include macOS, Windows (including WSL), and Linux. Requirements and setup defaults can change, so check the current installation guide before starting.

  1. Install a supported Node.js version.
  2. Run the project generator:
npx create-next-app@latest my-next-app

Follow the prompts. The documented default setup enables TypeScript, Tailwind CSS, ESLint, the App Router, Turbopack, and the @/* import alias. To use the generated defaults without customizing prompts, run:

cd my-next-app
npm run dev

Open http://localhost:3000 in a browser. Edit app/page.tsx to change the home page. For a production build, run:

npm run build
npm run start

Use the package manager and scripts generated for your project; equivalent commands may differ if you choose another package manager or change the setup.

7. Deploying Next.js

The deployment guide describes four broad choices. Node.js server and Docker support all Next.js features in its table; static export is limited; adapter support varies. Pick based on the features your app needs and who will operate its runtime. Deploying documentation

Mode When it fits Tradeoff to check
Node.js server You need runtime server features. You need an environment that can run the production server.
Docker You want to package the application in a container. You operate or select infrastructure that runs the container.
Static export The application fits a static output model and can be served by a static web server. Only limited features are supported; confirm that every required feature works in this mode.
Platform adapter You want to deploy through a provider’s adapter. Feature support varies by adapter; verify the specific features you rely on.

The documented Node.js production flow is npm run build followed by npm run start. Static output can be served by a static web server. The guide names examples such as DigitalOcean, Fly.io, Google Cloud Run, Render, and SST; those examples are not a ranking or endorsement.

8. Common problems and fixes

Symptom Likely cause What to check
Installation reports an unsupported Node version The installed runtime is below the documented minimum for the current guide. Check the current installation guide and install a supported version (20.9 minimum in the guide updated March 16, 2026).
useState or an event handler fails in a component The component is being treated as a Server Component. Move interactive behavior to a Client Component and add "use client" at that module’s top.
window or localStorage is undefined Browser-only code is running on the server. Access browser APIs from a Client Component at an appropriate client lifecycle point.
Data is stale or a request unexpectedly runs again Assumptions about fetch caching differ from the current defaults or configuration. Review the fetching and caching documentation for the installed version; the current fetching guide says fetch is not cached by default.
Page appears stuck while data loads A slow request is blocking the route’s rendered output. Use a loading boundary or Suspense to stream a fallback where suitable, and inspect the upstream request.
Works locally but a feature is absent after deployment The chosen deployment mode or adapter may not support that feature. Check the deployment feature matrix; static export is limited and adapter support varies.
Data belonging to another user is exposed Server-side rendering was mistaken for authorization. Authenticate and authorize access at the data operation; do not rely on UI visibility.

9. Performance, reliability, and cost considerations

  • Performance: Server Components and streaming provide rendering tools, not a universal speed guarantee. Measure real routes and inspect slow data sources and assets.
  • Reliability: Runtime-dependent features require an environment that supports the selected deployment mode. Confirm feature support and operational responsibilities before choosing static export or an adapter.
  • Data correctness: Decide which data can be cached and for how long. Treat caching defaults as version-dependent and protect personalized data with authorization.
  • Cost: The dossier does not establish hosting prices. Compare provider costs using your app’s runtime, traffic, storage, and operational needs rather than assuming a framework-wide price.

10. Capture a Next.js page as an image or PDF

During development, use your browser’s screenshot feature or a browser automation setup to capture a local route after it renders. For repeatable capture of a public page in a script, a screenshot API can return the image or PDF without you managing a browser. For example, ScreenshotNeo accepts a URL in one GET request. The API can return PNG, JPEG, WebP, or PDF; consult the ScreenshotNeo API documentation for parameters and output options.

Or skip the browser setup

Request a screenshot of a public URL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

Replace the example URL with your public page. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. See the API documentation or sign up for 1,000 free screenshots a month, no card required.

Frequently asked questions

Do I need to learn React before Next.js?

You can start with Next.js while learning React, but understanding components, props, state, and JSX makes the framework easier to use.

Can I use JavaScript instead of TypeScript?

Yes. The documented starter defaults enable TypeScript, but Next.js supports JavaScript files too.

Does Next.js make a site SEO-friendly automatically?

It provides rendering and metadata capabilities, but the framework alone cannot guarantee search rankings or correct metadata. Those depend on your implementation and content.

Can I keep using the Pages Router?

Yes. It remains supported. The docs recommend the App Router for projects that want React’s latest features.

Sources