Reading Next.js Docs
Summary after reading Next.js docs.
Next.js is a React framework for building full-stack web applications. You use React Components to build user interfaces, and Next.js for additional features and optimizations.
How to use the docs
The docs are organized into 4 sections:
- Getting Started: Step-by-step tutorials to help you create a new application and learn the core Next.js features.
- Guides: Tutorials on specific use cases, choose what's relevant to you.
- Deep Dive: In-depth explanations on how Next.js works.
- API Reference: Detailed technical reference for every feature.
Next.js has 2 sets of routers. The newer App Router that supports Server Components. The original pages router is still supported and being improved.
App Router
The App Router is a file-system based router that uses React's latest features such as Server Components, Suspense, and Server Functions.
Installation
The above command will prompt you to ask couple of questions.
There is a method to do manual installation.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
To run dev server :
Top Level Files
-
next.config.js
- Configuration file for Next.js -
package.json
- Project dependencies and scripts instrumentation.ts
- OpenTelemetry and Instrumentation filemiddleware.ts
- Next.js request middleware.env
- Environment variables.env.local
- Local environment variables.env.production
- Production environment variables.env.development
- Development environment variables.eslintrc.json
- Configuration file for ESLint.gitignore
- Git files and folders to ignorenext-env.d.ts
- TypeScript declaration file for Next.jstsconfig.json
- Configuration file for TypeScriptjsconfig.json
- Configuration file for JavaScript
Routing Files
layout .js .jsx .tsx Layout
page .js .jsx .tsx Page
loading .js .jsx .tsx Loading UI
not-found .js .jsx .tsx Not found UI
error .js .jsx .tsx Error UI
global-error .js .jsx .tsx Global error UI
route .js .ts API endpoint
template .js .jsx .tsx Re-rendered layout
default .js .jsx .tsx Parallel route fallback page
Nested Routes
Dynamic routes
[folder] Dynamic route segment
[...folder] Catch-all route segment
[[...folder]] Optional catch-all route segment
Route Groups and private folders
(folder) Group routes without affecting routing
_folder Opt folder and all child segments out of routing
Parallel and Intercepted Routes
@folder Named slot
(.)folder Intercept same level
(..)folder Intercept one level above
(..)(..)folder Intercept two levels above
(...)folder Intercept from root
Private Folders
Private folders can be created by prefixing it with an underscore.
Route Groups
Route groups are useful for:
- Organizing routes by site section, intent, or team. e.g. marketing pages, admin pages, etc.
- Enabling nested layouts in the same route segment level:
- Creating multiple nested layouts in the same segment, including multiple root layouts
- Adding a layout to a subset of routes in a common segment
Mutli-Layout Setup
To have multiple layouts.
Creating Layouts and Pages
Next.js uses file-system based routing, meaning you can use folders and files to define routes. This page will guide you through how to create layouts and pages, and link between them.
Creating a Page
A page is UI that is rendered on a specific route. To create a page, add a page file inside the app directory and default export a React component.
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,
}: {
children: React.ReactNode
}) {
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 layout above is called a root layout because it's defined at the root of the app directory. The root layout is required and must contain html and body tags.
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.
Images
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.
Note : The image tag should use the height and width attributes to avoid layout shifts.
Remote Images
To safely allow images from remote servers, you need to define a list of supported URL patterns in next.config.js. Be as specific as possible to prevent malicious usage. For example, the following configuration will only allow images from a specific AWS S3 bucket:
import type { NextConfig } from 'next'
const config: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
search: '',
},
],
},
}
export default config
Fonts
The next/font module automatically optimizes your fonts and removes external network requests for improved privacy and performance.
Google fonts
You can automatically self-host any Google Font. Fonts are included stored as static assets and served from the same domain as your deployment, meaning no requests are sent to Google by the browser when the user visits your site.
import { Geist } from 'next/font/google'
const geist = Geist({
subsets: ['latin'],
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={geist.className}>
<body>{children}</body>
</html>
)
}
CSS Usage
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.
To start using CSS Modules, create a new file with the extension .module.css and import it into any component inside the app directory:
import styles from './blog.module.css'
export default function Page() {
return <main className={styles.blog}></main>
}
Global CSS
You can use global CSS to apply styles across your application.
Create a app/global.css file and import it in the root layout to apply the styles to every route in your application:
How to use Server and Client Components
By default, layouts and pages are Server Components, which lets you fetch data and render parts of your UI on the server, optionally cache the result, and stream it to the client. When you need interactivity or browser APIs, you can use Client Components to layer in functionality.
When to use Server and Client Components?
The client and server environments have different capabilities. Server and Client components allow you to run logic in each environment depending on your use case.
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.
Using Client Components
You can create a Client Component by adding the "use client" directive at the top of the file, above your imports.
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>{count} likes</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
Passing data from Server to Client Components
You can pass data from Server Components to Client Components using props
import LikeButton from '@/app/ui/like-button'
import { getPost } from '@/lib/data'
export default async function Page({ params }: { params: { id: string } }) {
const post = await getPost(params.id)
return <LikeButton likes={post.likes} />
}
Preventing Server side code from rendering on client.
import 'server-only'
export async function getData() {
const res = await fetch('https://external-service.com/data', {
headers: {
authorization: process.env.API_KEY,
},
})
return res.json()
}
Fetching data
Server Components
You can fetch data in Server Components using:
- The fetch API
- An ORM or database
To fetch data with the fetch API, turn your component into an asynchronous function, and await the fetch call. For example:
export default async function Page() {
const data = await fetch('https://api.vercel.app/blog')
const posts = await data.json()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
To avoid caching use
{ cache: 'no-store' }
Client Components
There are two ways to fetch data in Client Components, using:
- React's use hook
- A community library like SWR or React Query
HOW TO CACHE AND REVALIDATE DATA
Caching is a technique for storing the result of data fetching and other computations so that future requests for the same data can be served faster, without doing the work again. While revalidation allows you to update cache entries without having to rebuild your entire application.
By default, fetch requests are not cached. You can cache individual requests by setting the cache option to 'force-cache'.
How to update data
You can update data in Next.js using React's Server Functions.
Server Functions
A Server Function is an asynchronous function that is executed on the server. Server Functions are inherently asynchronous because they are invoked by the client using a network request. When invoked as part of an action, they are also called Server Actions.
Deploying
How to deploy your Next.js application
Next.js can be deployed as a Node.js server, Docker container, static export, or adapted to run on different platforms.
Deployment Option | Feature Support |
---|---|
Node.js server | All |
Docker container | All |
Static export | Limited |
Adapters | Platform-specific |
Node.js server
Next.js can be deployed to any provider that supports Node.js. Ensure your package.json has the "build" and "start" scripts: