I. Creating a Project
npx create-next-app@latest
II. File-based routing mechanism

III. Dynamic Routing Parameters
Note: When matching URLs, static routes have higher priority than dynamic routes.
1. Basic usage

http://localhost:3000/about/1
http://localhost:3000/about/1
import {useRouter} from 'next/router' // Import the hook function
export default function AboutProjectPage() {
const router = useRouter() // Use the hook function
return (
<>
<div>
About Project. The id is: {router.query.id} // Get dynamic route parameters
</div>
</>
)
}
2. Multi-layer routing parameters
Multi-level routing parameters can also be used.


3. Multiple parameters



Turn into an array

IV. Route redirection
1、Link
(1) Basic usage
import Link from 'next/link';
<Link href="/">
Home Page
</Link>
(2) Passing in UrlObject
interface UrlObject {
auth?: string | null | undefined;
hash?: string | null | undefined;
host?: string | null | undefined;
hostname?: string | null | undefined;
href?: string | null | undefined;
pathname?: string | null | undefined;
protocol?: string | null | undefined;
search?: string | null | undefined;
slashes?: boolean | null | undefined;
port?: string | number | null | undefined;
query?: string | null | ParsedUrlQueryInput | undefined;
}

2. Programmatic navigation (router.push, router.replace)


3. 404 page
Create a special file named 404.js in the pages folder. Next.js will automatically load the component when a 404 error is returned.
This means users can customize the 404 page.
V. Static Files
Static files are placed in the root directory’s public folder. Next.js will handle this automatically. Static files placed outside this folder will not be accessible.
VI. CSS Module
1. Component Style
Next.js supports CSS modules through the naming convention of using the name of the js component as the .module.css file.
It only affects the component it is bound to.
2. Global Styles
Write globals.css in the styles directory of the root directory.

Introduction

VII. SSG
SSG stands for Static Site Generation, which means that pages are generated in advance during the file packaging stage.
Next.js pre-renders all pages without dynamic data by default, while dynamic data is rendered on the client side, just like React.
To display dynamic data in the HTML source code, you can use the `getStaticProps` method under `page`. This method runs in a server-side environment, retrieving and rendering data on the server side, and the client will not receive any code within the method.
In addition, Next.js has extended some features. For example, fetch is a browser interface that cannot be used on the server side, but the fetch API can be used in the getStaticProps method.
1、getStaticProps
The getStaticProps method returns values of the following types, with a total of three possibilities:
export type GetStaticPropsResult<P> =
| { props: P; revalidate?: number | boolean }
| { redirect: Redirect; revalidate?: number | boolean }
| { notFound: true; revalidate?: number | boolean }
(1) Basic usage

Generally, after successfully obtaining the data, the return value will be the first type.
(2)、revalidate
export async function getStaticProps() {
const filePath = path.join(process.cwd(), 'data', 'dummy-backend.json');
const jsonData = await fs.readFile(filePath);
const data=JSON.parse(jsonData);
return {
props:{
products: data.products
},
revalidate:10 //Re render pre rendering every 10 seconds
}
(3)、redirect、notFound
if (!data) {
return{
redirect: {
destination:'/no-data
}
}
}
if (data.products.length ===0) {
return { notFound:true }; //Go to 404 page
}
If data retrieval fails, guide the user to the next step, redirect, or directly return a 404 error.
(4) Obtain dynamic routing parameters (context)

pages/[pid].js
Unable to redirect to [pid].js
const productId = params.pid; //Obtain dynamic routing parameters
Because [pid] is dynamic, Next.js cannot render it in advance.
To use getStaticPaths
2、getStaticPaths
If you need to generate a static page from a JavaScript file whose filename contains square brackets [], you need to use the `getStaticPaths` method.
The `getStaticPaths` method defines a list of static pages to be generated. Each data item calls `getStaticProps` to retrieve the data, so `getStaticProps` must be defined before you can use `getStaticPaths`.
(1) Basic usage
pages/[pid].js

Opening the page at this point sends all the JSON data to the browser.

(2)、fallback
1. When the fallback value is false, if the URL request parameters are not defined in the paths property, a 404 page will be returned directly.
2. When `fallback` is set to `true`, navigating the page via the Link component will not cause any issues. However, accessing a path not listed in `paths` directly in the URL will result in an error. The React component needs to check the corresponding props parameter and return a loading message before the server is ready.

3. Besides a boolean value, `fallback` can also be assigned the value ‘blocking’. This blocks the request if the data is not ready when the page is requested, and waits for the page to finish rendering before returning to the page. Compared to the second case, this essentially eliminates the need for the component to make this check.

When the fallback value is true, if a non-existent request path is accessed, a 404 page can be returned directly by returning { notFound: true } in getStaticProps.
8. SSR
SSR stands for Server-Side Rendering. The getServerSideProps method can process each request, making it suitable for pages where data changes frequently.
You can only choose one of getStaticProps and getServerSideProps.
`getServerSideProps` is also a method that runs on the server. The `context` parameter of this method can retrieve all the data from the request. The type of `context` is as follows:
export type GetServerSidePropsContext<
Q extends ParsedUrlQuery = ParsedUrlQuery,
D extends PreviewData = PreviewData
> = {
req: IncomingMessage & {
cookies: NextApiRequestCookies
}
res: ServerResponse
params?: Q
query: ParsedUrlQuery
preview?: boolean
previewData?: D
resolvedUrl: string
locale?: string
locales?: string[]
defaultLocale?: string
}
getServerSideProps return value type:
export type GetServerSidePropsResult<P> =
| { props: P | Promise<P> }
| { redirect: Redirect }
| { notFound: true }
The return type of getServerSideProps is basically the same as that of getStaticProps, except that it lacks the revalidate property, because getServerSideProps will re-render for each request.
(1) Basic usage

9. Situations unsuitable for pre-rendering
- Pages with data that changes very frequently (such as stock data).
- Pages that are highly coupled with user identity (e.g., the user’s recent xxx xxx).
- Only a small portion of the data on the page is different.
In these situations, it’s still best to use `fetch` in `useEffect` on the client side to retrieve data. The Next.js team has also written a React hook library, SWR (https://swr.vercel.app), to simplify client-side requests, as shown in the example below:
The SWR hook resends a request to retrieve data every time the page gains focus.
npm i swr
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then((res) => res.json())
function Profile() {
const { data, error } = useSWR('/api/profile-data', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
return (
<div>
<h1>{data.name}</h1>
<p>{data.bio}</p>
</div>
)
}
10. Add Meta information
1. Basic Usage

2. Head component reuse


3. Globally applicable Head
A globally applicable Head component can be added to the _app.js file. Furthermore, identical head tags will be merged, with the rule being that the last rendered Head tag overrides the previously rendered Head tags.

Another globally special JS file is /pages/_document.js, and its default values are as follows:
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
The `_app.js` file is equivalent to the content within the `body` element, while `_document.js` is equivalent to the entire HTML document, being “outer” than the former. Note that the `head` component here uses a different import package than a regular page; don’t get them mixed up.
XI. Image Optimization
Next.js provides a solution for optimizing images—the Image component.
There are four advantages to using the Image component.
- Use appropriate sizes and formats for each device (when accessing the page using Chrome, images will be converted to WebP format).
- Prevent Cumulative Layout Shift
- Images are only loaded in the view.
- You can customize the image size.
// ...
import Image from 'next/image'
export default function About(props) {
return <>
{/* ... */}
<Image
src={'/img.jpeg'}
alt="Image"
width={100}
height={100}
/>
<img
src={'/img.jpeg'}
alt="Image"
/>
</>
}
Next.js will convert and cache the image of the appropriate size based on the width and height values of the image when the page requests the server.
12. API Routing
The JS files under the `/pages/api` directory do not export page components; Next.js maps these files to API endpoints of type `/api/*`. The Next.js team has built upon NodeJS’s `http` module, providing web server development capabilities similar to Express.
We can write server-side logic in these files, and like the getStaticProps method, this logic is not visible to the client.
The basic format of these API routes is as follows:
export default function handler(req, res) {
if (req.method === 'POST') {
// Handling POST requests
} else {
// Handling other HTTP method requests
}
}
1. Basic Usage
pages/index.js

POST request

GET request

pages/api/feedback.js
POST request


GET request

2. Dynamic API Routing


use

13. Deploy Next.js
1. Construction
There are two ways to build Next.js applications:
(1)、next build
The first method is the “standard build,” which uses the command `next build`. This is the method used for all builds before the course.
Using this method, we get an optimized front-end project plus a NodeJS server-side application. This server-side application provides features such as API routing, SSR, and page re-validation. Therefore, deploying this application requires a server with a NodeJS environment.
(2)、next export
The second build method is static packaging, which uses the command `next export` to build.
Code generated in this way will only contain pure front-end content: HTML, CSS, JS, and static resources. There is no NodeJS server-side program, so deployment does not require a NodeJS environment. However, features provided by Next.js, such as API routing and SSR, will not be available.
2. Configuration
The `next.config.js` file in the project root directory allows you to configure Next.js.
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig
The code in this file is also server-side code, used during the build process and in the generated NodeJS server application. Furthermore, this file will not be processed by Webpack, Babel, or TypeScript, so ensure that you use syntax that matches your machine’s NodeJS version.
For specific configuration options, please refer to the official documentation.
XIV. Encryption
The course uses the bcryptjs package to implement the encryption logic. Install it using the following command:
npm i bcryptjs
In the bcryptjs package, we only need to focus on two functions: the hash function and the compare function. Note that both methods are asynchronous.
import { hash, compare } from 'bcryptjs'
// ...
// Encrypt plaintext passwords using the hash function
const hashedPwd = await hash(pwd, 12)
// ...
// Compare two passwords using the compare function, returning a boolean value
const isValid = await compare(newPwd, hashedPwd)
15. Authentication
npm install next-auth
1. The backend generates a JWT token.
The `next-auth` package provides the logic needed for front-end and back-end authentication. In the API route, create a special file `/api/auth/[…nextauth].js`, import the `next-auth` package into the file, and implement the relevant logic:
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
export const authOptions = {
providers: [
CredentialsProvider({
name: 'Credentials',
session: {
strategy: "jwt",
},
async authorize(credentials, req) {
// Implement your own verification logic
const res = await fetch("/your/auth", {
method: 'POST',
body: JSON.stringify(credentials),
headers: { "Content-Type": "application/json" }
})
const user = await res.json()
// Return user information if everything is normal
if (res.ok && user) {
return user
}
// Return null if user information is not retrieved return
null
}
})
// ...other providers
],
}
export default NextAuth(authOptions)
2. In the front-end component, use the signIn function of the next-auth/react module to log in.
import { signIn } from "next-auth/react"
export default () => <button onClick={() =>
signIn('credentials', { redirect: false, username: 'username', password: 'password' })}>Login</button>
3. The client obtains authentication information through the useSession hook.
import { useSession } from "next-auth/react"
export default function About(props) {
const { data: session, status } = useSession()
console.log('session ', session)
console.log('status ', status)
return <>
{/* ... */}
</>
}
Version 4 of next-auth requires SessionProvider to use the hook mentioned above. Add the relevant code to _app.js:
import {SessionProvider} from "next-auth/react"
import '../styles/globals.css'
export default function App({Component, pageProps: {session, ...pageProps},}) {
return <SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
}
4. Log out the user using the signOut function of the next-auth/react module:
import { signOut } from "next-auth/react"
export default () => <button onClick={() => signOut()}>Logout</button>
XVI. Route Guard
On the client side, getSession can be used to obtain the current authentication information. On pages that require permissions, the value of the session can be checked to perform further operations.
On the server side, the unstable_getServerSession function can be used in the getStaticProps method to obtain the session. In version 4, getSession cannot be used on the server side.
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
export async function getServerSideProps(context) {
return {
props: {
session: await unstable_getServerSession(
context.req,
context.res,
authOptions
),
},
}
}