Recommended Free Tools
Next.js is a React framework for building full-stack web applications. For a new project, learn the App Router first: it is the current file-system router and uses React Server Components, Suspense, and Server Functions. Existing applications built with the Pages Router do not need an emergency rewrite; that router remains supported. This guide shows how to start, structure routes, choose server or client rendering, fetch fresh or cached data, stream slow work, secure the application, and verify a production build.
Choose the router before you write code
App Router for new work
The App Router uses an app directory. A route is created by folders, and a page.tsx file makes that route reachable. The root layout.tsx supplies shared HTML and UI. The Next.js documentation describes it as “a file-system based router that uses React’s latest features such as Server Components, Suspense, and Server Functions” (updated March 25, 2026).
Pages Router for established applications
The Pages Router uses a pages directory, with files such as pages/index.tsx and pages/api/*.ts. It remains supported in newer Next.js versions. Migrate route by route only when the App Router solves a concrete requirement; otherwise, keep the existing router and update it deliberately.
| Decision | Best fit | Trade-off |
|---|---|---|
| App Router | New applications and recent React features | Requires learning server/client boundaries and new data patterns |
| Pages Router | Existing production code and incremental maintenance | Does not provide the App Router model for new routes |
Create an application
The official quick start is create-next-app. Check the installation page for the requirements and defaults that match your installed version. The current canary installation source lists Node.js 20.9 as the minimum and supports macOS, Windows (including WSL), and Linux; these values can change.
#1 Best Overall
- Install a supported Node.js release.
- Run
npx create-next-app@latest my-app. - Choose TypeScript, linting, and the App Router when prompted. The generated project includes an
appdirectory and a root layout. - Enter the directory and start development:
cd my-app, thennpm run dev. - Open the local address printed by the command, edit
app/page.tsx, and save to see Fast Refresh.
Use the package manager and lockfile selected by your team. Do not assume a tutorial’s defaults match a later Next.js release.
Understand the App Router file structure
app/
layout.tsx # required root layout
page.tsx # /
loading.tsx # loading UI for this segment
error.tsx # client error boundary
blog/
page.tsx # /blog
[slug]/
page.tsx # /blog/:slug
public/ # static files
Layouts persist while navigating between child routes. A dynamic segment such as [slug] receives route parameters. Keep route-specific data and UI near the route, but put shared access rules and data functions in dedicated server modules.
Server Components and Client Components
App Router components are Server Components by default. They execute on the server and do not require JavaScript in the browser merely to render HTML. Use them for database queries, private environment variables, and static presentation. Add 'use client' at the top of a file when that component needs browser APIs, event handlers, state, or effects.
// app/products/page.tsx — Server Component
import AddToCart from './AddToCart'
export default async function ProductsPage() {
const products = await getProductsFromDatabase()
return <AddToCart products={products} />
}
// app/products/AddToCart.tsx — Client Component
'use client'
import { useState } from 'react'
export default function AddToCart({ products }) {
const [selected, setSelected] = useState(products[0]?.id)
return (
<button onClick={() => setSelected(products[0]?.id)}>
Add product {selected}
</button>
)
}
Keep the boundary as low as practical. A page does not need to become entirely client-rendered because one button is interactive. Props crossing the boundary must be serializable, so perform secrets and database work on the server and pass only the data the browser needs.
Rank #2
Fetch data with an explicit freshness decision
Server Components can perform asynchronous I/O with fetch or an ORM/database client. Identical fetch requests in a component tree are memoized by default, preventing duplicate work during one render. That does not mean every request is persistently cached: current guidance says fetch requests are not cached by default. Verify behavior for your Next.js version, API, and deployment.
Request-time data
// app/news/page.tsx — App Router Server Component
export default async function NewsPage() {
const response = await fetch('https://example.com/api/news', {
cache: 'no-store'
})
if (!response.ok) throw new Error('News request failed')
const stories = await response.json()
return <NewsList stories={stories} />
}
Use request-time work for data that must be current. Authentication state, request headers, cookies, or other request-time APIs can also make a route dynamic. Treat that behavior as an intentional choice rather than an accidental performance setting.
Reusable or cached data
For content that can be reused, opt into the caching mechanism documented for your installed release, including the use cache directive where supported. Set an invalidation strategy that matches the business requirement: product copy can tolerate reuse, while an account balance usually cannot. The production checklist recommends inspecting every important request instead of applying one global rule.
Stream slow work instead of blocking the whole page
A slow upstream service can delay the first complete response. Streaming lets fast parts appear while a slow section is still pending; it does not accelerate the upstream service.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #3
// app/dashboard/page.tsx
import { Suspense } from 'react'
import SlowReport from './SlowReport'
export default function Dashboard() {
return (
<main>
<h1>Dashboard</h1>
<Suspense fallback={<p>Loading report…</p>}>
<SlowReport />
</Suspense>
</main>
)
}
An adjacent loading.tsx can provide a segment-level fallback. Place a Suspense boundary close to uncached or slow work when users benefit from a more granular loading state. Make the fallback meaningful: preserve layout and explain what is loading rather than showing an unrelated spinner.
Security is still your responsibility
- Authenticate and authorize inside every Server Action; do not rely only on a proxy, layout, or page check.
- Move database access into a server-only data-access layer. Never send credentials or privileged query results to a Client Component.
- Keep
.env.*files out of Git. Only variables intentionally exposed to browsers should use theNEXT_PUBLIC_prefix. - Rate-limit expensive operations such as report generation, file processing, and external API calls.
- Validate input at the server boundary, including values submitted by your own UI.
Metadata, accessibility, and search visibility
Use the Metadata API for page titles and descriptions. Add Open Graph images, a sitemap, and a robots file when they fit the site. These mechanisms help crawlers and link previews; they are not guarantees of search ranking.
Give controls accessible names, preserve keyboard focus, provide useful form errors, and check headings and contrast. Server rendering does not automatically make an interface accessible.
Production checklist
- Exercise success, not-found, unauthorized, and error states for every important route.
- Review
use clientboundaries and remove client code that does not need interactivity. - Inspect request-time APIs, fetch caching, invalidation, and streaming fallbacks.
- Run type checking and linting; verify that environment variables are available only where intended.
- Analyze bundles and check Core Web Vitals on representative pages.
- Build and run the production output:
next build, thennext start. Test it with production-like environment variables and traffic patterns.
Or skip the browser setup
If your application needs automated page images for documentation, previews, visual regression, or social cards, you can capture the deployed URL with ScreenshotNeo instead of maintaining browser automation. It accepts consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →One GET request returns PNG, JPEG, WebP, or PDF. The API supports full-page and selector captures, device and viewport settings, dark mode, custom CSS and JavaScript, waits, request blocking, cookies, headers, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous jobs, bulk capture, and usage reporting. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Rank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-next-app.example -o shot.webp
See the ScreenshotNeo documentation for parameters and response headers. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting
“window is not defined”
The code is running in a Server Component. Move browser-only code into a small file marked 'use client', or replace it with a server-safe API.
A page is unexpectedly stale
Inspect the specific fetch options, cache directives, revalidation, and deployment cache. Do not infer behavior from an older tutorial that says all fetches are cached.
The first screen waits too long
Identify the slow request, then put it behind a nearby Suspense boundary or loading.tsx. Streaming changes delivery order, not upstream latency.
Best Value
Secrets appear in browser code
Check imports from Client Components and environment variable names. Remove privileged modules from the client graph and reserve NEXT_PUBLIC_ for deliberately public values.
Development works but production fails
Run next build and next start locally with production-like variables. Check case-sensitive paths, dynamic rendering assumptions, error boundaries, and external service permissions.
Frequently Asked Questions
Can I use the Pages Router and App Router in one project?
Yes, Next.js supports a gradual, project-specific transition. Keep existing Pages Router routes while introducing App Router routes where that provides a clear benefit, and verify shared layouts and data behavior carefully.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchDoes streaming make an API faster?
No. Streaming sends completed portions earlier while a slow portion waits; the upstream operation itself still takes the same time.
Where should a database query live?
Keep it in a server-only data-access module or Server Component. Expose only validated, necessary results to Client Components.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

