Next.js is the Web framework based on React, providing routing, server-side rendering, static generation, data acquisition, caching, SEO and back-end capabilities.
Compared with ordinary React SPA, the most important new capabilities of Next.js are:
- File system based App Router.
- React Server Components。
- SSR, SSG, ISR and other rendering strategies.
- Server-side data acquisition and caching.
- Metadata, Sitemap and other SEO functions.
- Route Handlers and Server Actions.
- Images, fonts and production build optimization.
1. Core concepts
| module | important concepts | priority |
|---|---|---|
| Routing | App Router、Layout、Dynamic Routes、Link | Must learn |
| Components | Server Components、Client Components、use client | Must learn |
| Rendering | SSR、SSG、CSR、Hydration | Must learn |
| Data | Server Fetching、Caching、Revalidation | Must learn |
| SEO | Metadata、Open Graph、Sitemap | Must learn |
| Assets | Image、Font、Static Assets | important |
| UX | Suspense、Streaming、Loading、Error | important |
| Backend | Route Handlers、Server Actions | on demand |
| Architecture | ISR、Cache Components、PPR | Advanced |
| Deployment | Static Export、Node Server、Docker | important |
The difference between Next.js and React + Vite
| Ability | React + Vite SPA | Next.js |
|---|---|---|
| React UI | support | support |
| Client routing | Usually use React Router | Built-in App Router |
| CSR | support | support |
| SSR | Need additional solutions | Built-in |
| SSG | Need additional solutions | Built-in |
| React Server Components | Does not belong to the default capabilities of ordinary Vite SPA | Built-in |
| API Routes | Requires independent backend | Route Handlers |
| SEO Metadata | self-management | Built-in Metadata API |
| Image optimization | Third-party tools or self-implementation | next/image |
| Data cache | Usually managed by TanStack Query etc. | Server cache + optional client cache |
| Production deployment | Usually static files | Static files or Node.js Server |
Next.js does not replace React, but adds routing, rendering, server-side functions and building conventions based on React.
2. Installation and project structure
Create project:
pnpm create next-app@latest my-site
Commonly used commands:
# development server
pnpm dev
# Production build
pnpm build
# Start production server
pnpm start
Typical project structure:
my-site/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ ├── globals.css
│ ├── loading.tsx
│ ├── error.tsx
│ ├── not-found.tsx
│ │
│ ├── about/
│ │ └── page.tsx
│ │
│ ├── blog/
│ │ ├── page.tsx
│ │ └── [slug]/
│ │ └── page.tsx
│ │
│ └── api/
│ └── health/
│ └── route.ts
│
├── components/
├── lib/
├── public/
├── next.config.ts
└── package.json
Among them:
app/: File system based routing.components/: Reusable components.lib/: Tool functions, data access, etc.public/: Static resources.next.config.ts: Next.js configuration.
3. App Router: File system routing
Next.js Define routes using files and folders.
For example:
app/
├── page.tsx
├── about/
│ └── page.tsx
└── blog/
└── [slug]/
└── page.tsx
Corresponds to:
/ → app/page.tsx
/about → app/about/page.tsx
/blog/react → app/blog/[slug]/page.tsx
/blog/typescript → app/blog/[slug]/page.tsx
special files
| File | function |
|---|---|
page.tsx | Define routing page |
layout.tsx | Define shared layout |
template.tsx | Like Layout, but instances can be recreated while navigating |
loading.tsx | Route loading status |
error.tsx | routing error boundary |
not-found.tsx | Not Found UI |
route.ts | HTTP Route Handler |
default.tsx | Parallel Routes defaults to UI |
Layout
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<header>My Website</header>
<main>{children}</main>
<footer>Copyright</footer>
</body>
</html>
);
}
Layout can be nested.
For example:
app/
├── layout.tsx
└── blog/
├── layout.tsx
└── page.tsx
blog/layout.tsx only applies to the Blog route and its sub-routes.
Sharing Layout usually keeps the mount state alive while the client navigates, avoiding unnecessary re-rendering and state loss.
4. Dynamic Routes
Dynamic routes are defined using square brackets:
app/blog/[slug]/page.tsx
Visit:
/blog/react-basics
Corresponds to:
type Props = {
params: Promise<{
slug: string;
}>;
};
export default async function BlogPage({ params }: Props) {
const { slug } = await params;
return <h1>{slug}</h1>;
}
In Next.js 15/16, params of App Router is Promise, which needs to be read asynchronously.
Catch-all Routes
[...slug]
For example:
/docs/react/hooks
Possible to get:
{
slug: ["react", "hooks"];
}
Optional Catch-all Routes
[[...slug]]
Can match zero or more path fragments.
5. Link and client navigation
Next.js provides next/link:
import Link from "next/link";
export default function Navbar() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/blog">Blog</Link>
<Link href="/about">About</Link>
</nav>
);
}
Main functions:
- Client navigation.
- Route prefetching.
- Reduce unnecessary full page refreshes.
- Works with App Router's client route cache.
useRouter
If you need to navigate within event handlers:
"use client";
import { useRouter } from "next/navigation";
export function NavigationButton() {
const router = useRouter();
return <button onClick={() => router.push("/blog")}>Open Blog</button>;
}
Commonly used methods:
| method | function |
|---|---|
router.push() | Navigate and add history |
router.replace() | Navigate and replace history |
router.back() | Return to previous page |
router.refresh() | Request new server content for the current route |
router.prefetch() | Prefetch routing |
router.refresh() does not mean clearing all server caches. If the data comes from a server-side cache that is still valid, you may still see the cached data after refreshing.
6. Server Components
In App Router, Page and Layout default to Server Component.
For example:
// app/blog/page.tsx
export default async function BlogPage() {
const posts = await getPosts();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Features of Server Component:
- Execute in server environment.
- Can directly access server-side databases, files or private API.
- async/await can be used.
- Does not send its own component implementation code to the browser as Client Component JavaScript.
- You cannot directly use
useState,useEffectand other clients Hook. - Browsers such as
window,documentand API cannot be accessed directly.
Value of Server Component
Browser Request
↓
Next.js Server
↓
Server Component
↓
Fetch Data
↓
Render RSC Payload / HTML
↓
Browser
This reduces the number of JavaScripts that the browser needs to perform and allows the data fetch to occur closer to the server resources.
Note: Server Component is executed on the server by default, which does not mean that it must be re-executed for every request; the actual behavior also depends on the pre-rendering and caching strategy.
7. Client Components
Use when browser interaction is required:
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
Client Component is suitable for:
useState、useEffect。- User interaction events.
- React Hook Form。
- TanStack Query Hooks。
- Browser API.
- Third-party components that require a browser environment.
The actual meaning of use client
"use client" declares client module boundaries.
The marked module and its static import dependencies will enter the client module graph.
But please note:
Client Component does not mean that the first screen is not generated by the server at all HTML.
Next.js can prerender the initial HTML of Client Component, and then the browser loads JavaScript and does Hydration.
Recommended component organization
BlogPage (Server Component)
│
├── ArticleContent (Server Component)
│
├── TableOfContents (Client Component)
│
└── LikeButton (Client Component)
Principles:
retains Server Component by default, and only divides the parts that require interaction into Client Component.
Don't randomly add "use client" to the entire page or root Layout just for convenience.
8. Combination of Server Component and Client Component
Server Component can import and render Client Component.
// app/blog/page.tsx
import LikeButton from "@/components/LikeButton";
export default async function BlogPage() {
const post = await getPost();
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
<LikeButton postId={post.id} />
</article>
);
}
Client Component:
"use client";
import { useState } from "react";
export default function LikeButton({ postId }: { postId: number }) {
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>{liked ? "Liked" : "Like"}</button>
);
}
When Server Component passes Props to Client Component, the data usually needs to meet the serialization requirements of React.
Ordinary functions cannot be transferred across the Server/Client boundary at will; Server Functions has a special transfer mechanism.
9. SSR、SSG、CSR、ISR
These four concepts mainly describe rendering and content update strategies.
| mode | meaning | Applicable scenarios |
|---|---|---|
| CSR | Mainly render page content in the browser | Highly interactive applications |
| SSR | HTML is generated on the server when requested | Live or personalized content |
| SSG | HTML is pre-generated at build time | Blogs, documents |
| ISR | Update generated content by policy after deployment | Regularly updated pages |
CSR
Browser
↓
Load HTML + JavaScript
↓
React Executes
↓
Fetch Data
↓
Render UI
Typical application: ordinary React SPA.
SSR
Browser
↓
Request Page
↓
Server Fetches Data
↓
Server Renders HTML
↓
Browser Receives HTML
↓
Hydration
Suitable for pages where the content needs to be determined at request time.
SSG
Build Time
↓
Generate HTML
↓
Deploy Static Files
↓
Browser
Suitable for less changing content such as blogs, documents, About pages.
ISR
Static Content
↓
Cache Lifetime / Revalidation
↓
Regenerate or Refresh
↓
Updated Content
Instead of simply rebuilding the entire website in the background at regular intervals, ISR uses the Next.js caching and revalidation mechanism to update the corresponding content.
In Next.js 16, the corresponding configuration model should be selected depending on whether Cache Components is used.
10. Hydration
Hydration means React takes over HTML provided by the server in the browser and establishes interactive capabilities.
Server Generated HTML
↓
Browser Displays HTML
↓
Download Client JS
↓
React Hydration
↓
Interactive UI
For example, the server has output:
<button>Count: 0</button>
After the browser completes Hydration, this button obtains the interactive behavior defined by React.
Hydration Mismatch
A Hydration error may occur if the HTML generated by the server is inconsistent with the first rendering result of the browser.
Common reasons:
- The rendering stage reads
windoworlocalStoragedirectly. - The server and client output different times.
- Use unfixed random values.
- Inconsistent conditional rendering.
- Invalid HTML nesting.
The principle is to ensure that the first round of server-side and client-side rendering results are consistent.
11. Server-side Data Fetching
Server Component can directly perform asynchronous operations.
export default async function BlogPage() {
const response = await fetch("https://api.example.com/posts");
if (!response.ok) {
throw new Error("Failed to fetch posts");
}
const posts = await response.json();
return <PostList posts={posts} />;
}
The difference between getting data from the client
Server Fetching:
Next.js Server
↓
External API / Database
↓
Server Component
↓
Rendered Result
Client Fetching:
Browser
↓
TanStack Query
↓
Axios / Fetch
↓
Backend API
Server Fetching suitable for:
- Article content.
- SEO related data.
- Public data that needs to be displayed on the first screen.
- You don't want to expose your private API credentials to the browser's data access.
Client Fetching suitable for:
- Highly interactive data.
- Data that needs to be continuously updated.
- User action driven queries.
- Local caching and optimistic updates.
The two can be mixed.
12. Next.js caching mechanism
Caching is a more complex part of App Router because different versions have different configuration models.
Need to distinguish:
| cache type | Main function |
|---|---|
| Request Memoization | Deduplication within the same React server-side rendering |
| Server Data / Cache Components Cache | Reuse server-side data or component results between requests |
| Router Cache | Browser cache routing related RSC Payload |
| Browser HTTP Cache | Cache JS, CSS, pictures and other static resources |
Request Memoization
In the same Server Component rendering, the same GET Fetch request can reuse the results.
const post1 = await fetch(url);
const post2 = await fetch(url);
Duplicate actual requests can be avoided when the same request conditions are met.
But it's not equivalent to persistent caching across HTTP requests.
Default fetch behavior
In modern Next.js App Router:
const response = await fetch(url);
Persistent data caching is not used by default.
If a page needs to reuse data across requests, an appropriate caching strategy needs to be adopted.
The following mainly introduces the Cache Components model of Next.js 16.
13. Cache Components
Enable:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;
cacheComponents has access to the following abilities:
"use cache"。cacheLife()。cacheTag()。revalidateTag()。updateTag()。- Partial pre-rendering in collaboration with Suspense.
Cache Components does not mean that all content is automatically cached, but that the developer explicitly declares that it is suitable for reuse.
use cache
import { cacheLife } from "next/cache";
export default async function BlogPage() {
"use cache";
cacheLife("hours");
const posts = await getPosts();
return <PostList posts={posts} />;
}
What is cached here is the result of the function or component, not just a certain Fetch Response.
cacheLife
cacheLife("hours");
Used to declare cache life cycle.
Custom caching policies can also be configured.
cacheTag
import { cacheTag } from "next/cache";
export async function getPosts() {
"use cache";
cacheTag("posts");
return fetchPostsFromDatabase();
}
Tag enables multiple related caches to be revalidated with the same identifier.
14. Revalidation: cache revalidation
Next.js 16 Cache Components provides several important methods.
revalidateTag
import { revalidateTag } from "next/cache";
revalidateTag("posts", "max");
Mark the relevant cache as expired and update it using the Stale-While-Revalidate pattern.
In other words, it is allowed to return the old content before performing a background refresh.
Suitable for content such as blogs and product catalogs that can tolerate short-term stale data.
updateTag
import { updateTag } from "next/cache";
updateTag("posts");
Immediately invalidate the relevant cache and the next read needs to get new data instead of continuing to return the old content.
updateTag() can only be used with Server Actions.
revalidatePath
import { revalidatePath } from "next/cache";
revalidatePath("/blog");
Revalidate relevant caches following routing paths.
Contrast
| method | function | Common uses |
|---|---|---|
cacheLife | Define cache lifecycle | Update regularly |
cacheTag | Tag cache | Cache grouping |
revalidateTag | Invalidate and refresh in the background | Blog, content list |
updateTag | Invalid immediately | Instant consistency after user submission |
revalidatePath | Re-verify by path | Page content update |
The cache invalidation management here occurs on the Next.js server, which does not belong to the same cache system as TanStack Query's queryClient.invalidateQueries().
15. Suspense and Streaming
Next.js supports React Suspense and streaming rendering.
Suspense
import { Suspense } from "react";
export default function Page() {
return (
<main>
<h1>Dashboard</h1>
<Suspense fallback={<p>Loading...</p>}>
<Analytics />
</Suspense>
</main>
);
}
Allows waiting for asynchronous results to be placed separately into the load boundary.
Streaming
Browser Request
↓
Server
│
├── Send Static HTML
│
├── Send Loading UI
│
└── Send Async Content Later
This eliminates the need to wait for all data to be retrieved before sending the entire page.
loading.tsx
// app/blog/loading.tsx
export default function Loading() {
return <p>Loading blog...</p>;
}
Next.js will establish a loading boundary for the corresponding route.
16. Error Handling
error.tsx
"use client";
export default function ErrorPage({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<p>Something went wrong.</p>
<button onClick={reset}>Try again</button>
</div>
);
}
error.tsx is the routing segment error boundary and Client Component is required.
It is primarily intended to handle errors that can be caught by Error Boundary in the corresponding component tree, and is not meant to catch all types of server or event handling errors.
not-found.tsx
export default function NotFound() {
return <h1>Page not found</h1>;
}
Cooperation:
import { notFound } from "next/navigation";
if (!post) {
notFound();
}
The Not Found page can be displayed.
17. Metadata and SEO
Next.js provides Metadata API to facilitate the generation of SEO meta information for pages.
static Metadata
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "My Blog",
description: "Articles about programming and technology",
};
Dynamic Metadata
import type { Metadata } from "next";
type Props = {
params: Promise<{ slug: string }>;
};
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await getPost(slug);
return {
title: post.title,
description: post.summary,
};
}
Suitable for dynamic blog posts.
Open Graph
export const metadata: Metadata = {
title: "My Blog",
openGraph: {
title: "My Blog",
description: "Programming articles",
type: "website",
images: ["/og-image.png"],
},
};
Sitemap
// app/sitemap.ts
import type { MetadataRoute } from "next";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: "https://example.com",
lastModified: new Date(),
},
{
url: "https://example.com/blog",
lastModified: new Date(),
},
];
}
You can also use file conventions to generate robots.txt, Open Graph pictures, etc.
Note: SSR/SSG is helpful for search engines to directly obtain content, but it does not mean that using Next.js will automatically obtain a good SEO ranking.
18. generateStaticParams
Dynamic routing can use generateStaticParams() to pre-generate known pages during the build phase.
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
For the Markdown or MDX blog, you can get the article Slug at build time and generate the corresponding page.
Markdown Files
↓
generateStaticParams()
↓
Known Slugs
↓
Static Blog Pages
This is very useful for personal blogs.
If pure static export is required, you must also ensure that all dynamic routes meet the restrictions of static export.
19. next/image
Next.js provides built-in Image components.
import Image from "next/image";
export default function Profile() {
return <Image src="/avatar.jpg" alt="Avatar" width={300} height={300} />;
}
Main functions:
- Responsive images.
- Image size optimization.
- Reduce layout offset.
- Native Lazy Loading.
- Provide optimized image resources according to the environment.
For remote pictures, the allowed remote sources need to be configured in next.config.ts.
Note: Default dynamic image optimization usually requires a running environment that supports image optimization. When exporting purely statically, you should use custom Loader or turn off built-in optimization and other compatible methods.
20. next/font
Next.js supports font loading and optimization.
For example:
import { Geist } from "next/font/google";
const geist = Geist({
subsets: ["latin"],
});
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={geist.className}>{children}</body>
</html>
);
}
Main values:
- Optimize font loading.
- Reduce unnecessary font network requests.
- Reduce layout shift caused by font switching.
- Supports build-time self-hosting of font resources.
21. Route Handlers
Next.js can be defined using route.ts to define HTTP API.
For example:
// app/api/health/route.ts
export async function GET() {
return Response.json({
status: "ok",
});
}
Corresponds to:
GET /api/health
You can also use POST:
export async function POST(request: Request) {
const body = await request.json();
return Response.json({
received: body,
});
}
Route Handlers supports common HTTP methods:
GET
POST
PUT
PATCH
DELETE
HEAD
OPTIONS
Relationship with Django DRF
If the project already uses Django REST Framework as the backend:
Next.js Frontend
↓
Django DRF API
↓
PostgreSQL
It is not necessarily necessary to rewrite a set of API through Next.js Route Handlers.
Route Handlers can be used for:
- Lightweight backend interface.
- Webhook。
- Some server-side proxy or aggregation.
- Next.js exclusive server function.
22. Server Actions / Server Functions
Server Actions allows client interaction to trigger server functions.
For example:
// app/actions.ts
"use server";
export async function createPost(formData: FormData) {
const title = formData.get("title");
// Validate input and check authorization
// Save post to database
}
Form:
import { createPost } from "./actions";
export default function PostForm() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
);
}
Execution process:
Browser Form
↓
Server Action
↓
Validation / Authorization
↓
Database / Backend API
↓
Revalidation
↓
Updated UI
Server Actions is suitable for processing form submission, data modification and other operations.
Need to pay attention to:
- Server Actions is not an ordinary front-end function.
- Client calls trigger server communication.
- Server-side validation and permission checks must be performed.
- You should not assume that functions are inherently safe as long as they are written in a server file.
- Not suitable as a replacement for all legacy HTTP API.
If you already have a complete API architecture of Django + Orval + TanStack Query, there is no need to force migration to Server Actions.
23. proxy.ts
In Next.js 16, proxy.ts replaces the old Middleware file naming convention.
For example:
// proxy.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function proxy(request: NextRequest) {
return NextResponse.next();
}
Can be used for:
- Request redirect.
- URL rewrite.
- Some access control pre-logic.
- Routing is performed based on the request information.
However, it is not recommended to perform a large number of complex database operations in Proxy.
In addition, the front-end permission check in Proxy cannot replace the real authentication and authorization in the backend.
For example, interfaces involving user private data must still verify permissions in the actual server-side processing logic.
24. Turbopack
Turbopack is the build tool for Next.js.
Key goals include:
- Speed up development server startup.
- Improve incremental compilation efficiency.
- Reduce update feedback time for large projects.
- Supports development and production build processes for Next.js.
It and Vite are both construction tool-related technologies, but the service framework ecology and implementation methods are different.
React + Vite
↓
Vite Build Pipeline
Next.js
↓
Turbopack
Next.js 16 has made Turbopack the default builder for development and production builds.
Some projects that require special build configurations still need to check plugin and build compatibility.
25. Static Export
Next.js can be built as a static website.
Configuration:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "export",
};
export default nextConfig;
Execution:
pnpm build
Typically generates:
out/
├── index.html
├── about.html
├── blog/
└── _next/
└── static/
It can then be handed to Nginx, object storage, or CDN.
Limitations of Static Export
Purely static exports do not support functions that depend on the server performing the request, such as:
- Dynamic SSR.
- Server Actions。
- Route Handlers requiring server processing.
- Read the dynamic page of Cookie/Header on request.
- Dynamic image optimization relying on Next.js server.
- Proxy。
But Server Components does not necessarily mean that the Node.js server is required to run for a long time.
Server Components can still participate in static pre-rendering if the required data is available at build time.
26. Node.js Server and Docker
If you need SSR, Server Actions, dynamic data and other functions, you can deploy Node.js server.
Start:
pnpm build
pnpm start
It is also possible to configure the Standalone output:
// next.config.ts
const nextConfig = {
output: "standalone",
};
export default nextConfig;
Standalone produces output more suitable for standalone server deployments.
Typical architecture:
Browser
↓
Nginx
↓
Next.js Node Server
│
├── Server Components
├── Route Handlers
├── Server Actions
└── Static Assets
If Django is used simultaneously:
Browser
↓
Nginx
│
├── / → Next.js
│
└── /api/ → Django DRF
Docker deployment
Multi-stage Dockerfile can be used:
Stage 1: Install Dependencies
↓
Stage 2: Next.js Build
↓
Stage 3: Production Runtime
If static export is used, the final image can only contain Nginx.
If dynamic server rendering is used, the Node.js runtime environment or other supported deployment platform is required.
27. Next.js and TanStack Query
The server-side data acquisition of Next.js and TanStack Query are not mutually exclusive.
Server Component
Suitable for directly obtaining server data:
export default async function Page() {
const posts = await getPosts();
return <PostList posts={posts} />;
}
Client Component
Good for content that requires interactivity and client-side caching:
"use client";
function Profile() {
const { data } = useUserProfileRetrieve();
return <div>{data?.username}</div>;
}
Selection principles
| scene | Prioritize |
|---|---|
| Blog post text | Server Component |
| SEO content | Server Fetching |
| Public, more stable data | Server Cache |
| Profile editing | Client Component + RHF |
| Complex filter search | TanStack Query |
| Optimistic update | TanStack Query |
| form submission | Server Actions or Mutation |
| real-time interactive data | Client Fetching / Subscribe |
There is no need to delete the existing TanStack Query just because Next.js is adopted.
But there is no need to change all Server Components to Client Components in order to use TanStack Query.
28. Next.js FAQ
Q1: Does Next.js completely replace React Router?
For Next.js projects using App Router, React Router is generally no longer required.
Because Next.js already provides file system routing and client navigation.
Q2: Does the Next.js page default to all SSR?
no.
The page may be pre-rendered, dynamically rendered, partially pre-rendered, or may include client-side rendering.
We cannot simply think that Next.js = SSR.
Q3: Is Server Component necessarily faster than Client Component?
uncertain.
Server Component can usually reduce the client JavaScript, but may also increase the waiting time for server calculation and data acquisition.
Actual performance depends on content type, caching strategy, network conditions, and component structure.
Q4: Can Server Component be used with React Hook Form?
React Hook Form which relies on client Hook cannot be used directly.
The form should be placed in Client Component.
Q5: Is Next.js suitable for purely static personal blogs?
Suitable.
Can be combined with:
- MDX。
- App Router。
- generateStaticParams。
- Metadata。
- Static Export。
But if the website is mainly purely static content, you can also consider tools that are more focused on content sites such as Astro and Hugo.
Q6: Does Next.js require a separate backend?
no.
Next.js provides Route Handlers and Server Actions.
But if the project already has a complete backend like Django DRF, Next.js can focus on front-end rendering and SEO, without having to repeatedly build the same business backend.
Summary
The core knowledge of Next.js can be divided into four levels:
| level | core concepts |
|---|---|
| basic routing | App Router、Layout、Dynamic Routes、Link |
| render model | Server Component、Client Component、SSR、SSG、Hydration |
| Data and caching | Server Fetching、use cache、cacheLife、Revalidation |
| Engineering capabilities | Metadata、Streaming、Route Handlers、Server Actions、Deployment |
Recommended learning order:
- App Router and file routing.
- Server Components and Client Components.
- SSR, SSG, CSR and Hydration.
- Server-side Data Fetching。
- Metadata and SEO.
- Suspense, Streaming and Error Handling.
- Cache Components and Revalidation.
- Route Handlers、Server Actions。
- Static Export, Docker and production deployments.
The core architecture can be summarized as:
React Components
↓
Next.js App Router
│
├── Server Components
│ ├── Data Fetching
│ ├── Server Cache
│ └── HTML / RSC Payload
│
└── Client Components
├── React Hooks
├── User Interaction
├── React Hook Form
└── TanStack Query
↓
Backend API
The main value of Next.js is not to allow all React code to run on the server, but to allow developers to choose the appropriate server-side and client-side rendering methods based on data, interaction, caching and SEO needs.