
What is Next.js?
Next.js is a React framework for building full-stack web applications.
What is React?
React lets you build user interfaces out of individual pieces called components. Create your own React components like Thumbnail, LikeButton, and Video. Then combine them into entire screens, pages, and apps.
Some Next.js Benefits
- Automatic image, font, and script optimizations for improved UX and Core Web Vitals (Learn more)
- Client and server rendering
- Content pre-fetching with the <Link> component when the link is hovered or enters the viewport
- Client-side navigation (JavaScript-based page transitions) using the <Link> component, which is faster than default browser-based navigation using the <a> tag
- Optimized CSS
- Layouts (shared UI) don’t rerender on navigation from one page to another
- Automatic configuration of low-level tools like bundlers and compilers
- and much more
App Router and Pages Router
Next.js supports two different routers: App router and Pages router. The App router is newer and supports new React features.
Pre-requisite knowledge
In order to successfully use Next.js, you should know
- HTML Learn on w3schools
- CSS Learn on w3schools
- JavaScript Learn on w3schools
- React Learn on w3schools
Knowledge of the following is optional but recommended
- TypeScript – Learn on w3schools
- SQL – Learn on w3schools
- Git – Learn on w3schools
- NodeJS – Learn on w3schools
Installation
- Install Node.js 18.18 or later.
- Run
npx create-next-app@latest

After the prompts, create-next-app will create a folder with your project name and install the required dependencies.
You will get a folder structure like this

The “app” folder is where you source code is.

If you were using a the Pages router, your source code would be in a “pages” folder instead.
During installation, if you chose to have your code in a “src” folder, then the “app” or “pages” folders would be nested in a “src” folder.
The “public” folder is where you store static assets like images, fonts, etc.

In package.json, you will have some scripts like
next devstarts the development servernext buildbuilts the application for productionnext startstarts the production servereslintruns ESLint (for linting)

create-next-app created a starter home page (page.js) and layout (layout.js).
Run npm run dev to start the dev server.

Open http://localhost:3000/ in a browser to see the starter page.

Project Structure
View a listing of the various types of files in an Next.js app.
File-system-based Routing
Each folder represents a route segment that is mapped to a corresponding segment in a URL path. But, a route is not publicly accessible until a page.js or route.js file is added to a route segment.

Creating a Page
A page is UI that is rendered on a specific route.

export default function Page() {
return <h1>Hello Next.js!</h1>
}
Creating a Layout
A layout is UI that is shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not rerender.

export default function DashboardLayout({ children }) {
return (
<html lang="en">
<body>
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
<main>{children}</main>
</body>
</html>
)
}
The above is a root layout. It is required and must contain html and body tags.
You can also create nested layouts. Parent layouts wrap children layouts.
Dynamic segments
Dynamic segments allow you to create routes that are generated from data. For example, instead of manually creating a route for each individual blog post, you can create a dynamic segment to generate the routes based on blog post data. In the example below, [slug] is a dynamic segment.

app/blog/[slug]/page.js
export default async function BlogPostPage({ params }) {
const { slug } = await params
const post = await getPost(slug)
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
)
}
Server vs Client Components
Server components are components that are dynamically rendered on the server.
Client components are components that are statically rendered on the client (browser).
Rendering with search params
In a Server Component page, you can access search parameters using the searchParams prop:
app/page.jsx
export default async function Page({ searchParams }) {
const filters = (await searchParams).filters
}
Dynamic rendering
Using searchParams opts your page into dynamic rendering because it requires an incoming request to read the search parameters from. Use the searchParams prop when you need search parameters to load data for the page (e.g. pagination, filtering from a database).
Static rendering
Client Components can read search params using the useSearchParams hook. Use useSearchParams when search parameters are used only on the client (e.g. filtering a list already loaded via props).
Linking between pages
You can use the <Link> component to navigate between routes. <Link> is a built-in Next.js component that extends the HTML <a> tag to provide prefetching and client-side navigation. Next.js automatically prefetches routes linked with the <Link> component when they enter the user’s viewport.
import Link from 'next/link'
export default function Layout() {
return (
<html>
<body>
<nav>
{/* Prefetched when the link is hovered or enters the viewport */}
<Link href="/blog">Blog</Link>
{/* No prefetching */}
<a href="/contact">Contact</a>
</nav>
{children}
</body>
</html>
)
}
Linking and Navigation
Server Rendering
There are two types of server rendering, based on when it happens:
- Static Rendering (or Prerendering) happens at build time or during revalidation and the result is cached.
- Dynamic Rendering happens at request time in response to a client request.
Prefetching
Prefetching is the process of loading a route in the background before the user navigates to it. How much of the route is prefetched depends on whether it’s static or dynamic:
- Static Route: the full route is prefetched.
- Dynamic Route: prefetching is skipped, or the route is partially prefetched if
loading.tsxis present.
Prefetching happens when the link enters the viewport. If this consumes too much resources, you can just prefetch only on hover.
app/ui/hover-prefetch-link.js
'use client'
import Link from 'next/link'
import { useState } from 'react'
function HoverPrefetchLink({ href, children }) {
const [active, setActive] = useState(false)
return (
<Link
href={href}
prefetch={active ? null : false}
onMouseEnter={() => setActive(true)}
>
{children}
</Link>
)
}
Streaming
Client-side transitions
Traditionally, navigation to a server-rendered page triggers a full page load. Next.js avoids this with client-side transitions using the <Link> component. Instead of reloading the page, it updates the content dynamically by:
- Replacing the current page with the prefetched loading state or a new page if available.
- Keeping any shared layouts and UI.
Server and Client Components
Layouts and Pages are Server Components by default.
<Link> is a Client Component.
Use Client Components when you need:
- State and event handlers. E.g.
onClick,onChange. - Lifecycle logic. E.g.
useEffect. - Browser-only APIs. E.g.
localStorage,window,Navigator.geolocation, etc. - Custom hooks.
Use Server Components when you need:
- Fetch data from databases or APIs close to the source.
- Use API keys, tokens, and other secrets without exposing them to the client.
- Reduce the amount of JavaScript sent to the browser.
- Improve the First Contentful Paint (FCP), and stream content progressively to the client.
For example, the <Page> component is a Server Component that fetches data about a post, and passes it as props to the <LikeButton> which handles client-side interactivity.

Note that the <LikeButton> component has ‘use client’ at the top.
What is hydration?
Hydration is React’s process for attaching event handlers to the DOM, to make the static HTML interactive.
Pre-rendering vs no pre-rendering
With pre-rendering (using Next.js), HTML is rendered on the server (server-side static rendering) and sent to the client (browser), similar to how PHP works. Then JS loads in the browser to “hydrate” the DOM to make it interactive, including links that were created using the <Link> component rather than the <a> tag. If you disable JavaScript in the brower and load a page, the page will load, but it will not be interactive.
If you create a plain React.js app, then all page content is generated dynamically in the browser by JavaScript as a single-page application (SPA). That is why if you disable JavaScript in the brower and load a page, the page will load, but you won’t see anything.

Next.js has 2 kinds of pre-rendering:
- Static Generation is the pre-rendering method that generates the HTML at build time. The pre-rendered HTML is then reused on each request. This is like using Next.js as a static site generator.
- Server-side Rendering is the pre-rendering method that generates the HTML on each request. This is like how PHP sites, like WordPress, work.

Fetching Data
You can fetch data in Server and Client Components.
Fetching data in server components
You can fetch data in Server Components using:
- The
fetchAPI - An ORM or database
With the fetch API
To fetch data with the fetch API, turn your component into an asynchronous function, and await the fetch call. For example:

With an ORM or database
Since Server Components are rendered on the server, you can safely make database queries using an ORM or database client. Turn your component into an asynchronous function, and await the call:

Fetching data in client components
There are two ways to fetch data in Client Components, using:
- React’s
usehook - A community library like SWR or React Query
Updating Data
You can update data in Next.js using React’s Server Functions. A Server Function is an asynchronous function that runs on the server. They can be called from client through a network request, which is why they must be asynchronous.
Define a Server Function by using the “use server” directive at the top of an asynchronous function.

Server Functions can be inlined in Server Components by adding the "use server" directive to the top of the function body:

There are two main ways you can invoke a Server Function:
- Forms in Server and Client Components
- Event Handlers and useEffect in Client Components
Forms
React extends the HTML <form> element to allow Server Function to be invoked with the HTML action prop.

Event Handlers
You can invoke a Server Function in a Client Component by using event handlers such as onClick.

Show a pending state with a loading indicator
Revalidating
After performing an update, you can revalidate the Next.js cache and show the updated data by calling revalidatePath or revalidateTag within the Server Function:

Redirecting
You may want to redirect the user to a different page after performing an update. You can do this by calling redirect within the Server Function.

Cookies
You can get, set, and delete cookies inside a Server Action using the cookies API:

CSS
Tailwind CSS
CSS Modules
CSS Modules locally scope CSS by generating unique class names. This allows you to use the same class in different files without worrying about naming collisions. Learn more

Global CSS
You can use global CSS to apply styles across your application.

Next.js recommends using
- global styles for truly global CSS (like Tailwind’s base styles),
- Tailwind CSS for component styling, and
- CSS Modules for custom scoped CSS when needed.
External Stylesheets

In React 19, <link rel="stylesheet" href="..." /> can also be used.
Image Optimization
The Next.js <Image> component extends the HTML <img> element to provide:
- Size optimization: Automatically serving correctly sized images for each device, using modern image formats like WebP.
- Visual stability: Preventing layout shift automatically when images are loading.
- Faster page loads: Only loading images when they enter the viewport using native browser lazy loading, with optional blur-up placeholders.
- Asset flexibility: Resizing images on-demand, even images stored on remote servers.

The src property can be a local or remote image.
Better to store images locally, if possible. Next.js will automatically determine the intrinsic width and height. These values are used to determine the image ratio and prevent Cumulative Layout Shift while your image is loading.

Font Optimization
Metadata
Static metadata
To define static metadata, export a Metadata object from a static layout.js or page.js file.

Package Managers
Next.js recommends using pnpm as it’s faster and more efficient than npm or yarn.
npm install -g pnpm
Then, to install packages, run pnpm i
To start the dev server, run pnpm dev
Common Folder Structure
/app: Contains all the routes, components, and logic for your application, this is where you’ll be mostly working from./app/lib: Contains functions used in your application, such as reusable utility functions and data fetching functions./app/ui: Contains all the UI components for your application, such as cards, tables, and forms./public: Contains all the static assets for your application, such as images.
Demo
This GitHub repo contains pages that demonstrate some of the concepts above. Browse the repo to see the code structure. The demo site is hosted on Vercel, the makers of Next.js.































































































































