Next.js 13 is the latest release of the popular React framework, and it introduces several exciting features and improvements. In this blog post, we’ll cover the key highlights of Next.js 13 and what you need to know about them.
Table of Contents
- 1. App Directory
- 2. Streaming
- 3. Data Fetching
- 4. Turbopack
- 5. Improved Image Component
- 6. New Font Component
- 7. Improved Link Component
- Conclusion
1. App Directory
Next.js 13 introduces the app directory, which improves the routing experience in Next.js. The app directory became stable with the release of Next.js 13.4. With the app directory, you can easily share UI between routes, preserve state, and avoid expensive re-renders. It also includes support for server components, streaming, and data fetching.
Note: The /app
directory works alongside the existing /pages
directory in Next.js and allows for incremental adoption. This means that you can choose to opt some routes of your application into the new behavior provided by the App Router while keeping other routes in the “pages” directory for the previous behavior.
The App Router takes priority over the Pages Router. Routes across directories should not resolve to the same URL path to prevent conflicts, and if they do, a build-time error will occur.
Understanding Client Components
By default, components inside the /app
directory are Server Components. However, you can also use Client Components in the /app directory by putting the "use client"
directive at the top of the file.
How do you know when a component is a Client component? Client Components enable adding client-side interactivity to the application. They are pre-rendered on the server and hydrated on the client. These components use features like useState
, useEffect
, and other browser APIs to handle interactivity and user interactions. Client Components are responsible for updating the UI dynamically on the client-side and are especially useful for interactive features like handling clicks, user inputs, and state management.
Note: If you try to use React hooks (useState, useEffect, useContext, etc.) inside of a server component you will get an error. To fix this, convert the component to a Client component by adding the "use client"
directive to the top of the file. Remember, components in the app directory are server components by default.
Understanding Server Components
Server Components are components that are primarily rendered on the server. They are non-interactive and can be used for parts of the UI that don’t require client-side interactivity. Server Components allow developers to better leverage server infrastructure and improve performance by moving data fetching and large dependencies closer to the server. These components are rendered on the server during the initial page load, reducing the client-side JavaScript bundle size. Server Components are also cacheable and predictable in size, making them efficient for server rendering.
Difference between Client and Server Components
Here are code snippets to illustrate the difference between a Server and a Client Component:
Server Component Example:
// This is a Server Component
// It is rendered primarily on the server-side
export default function ServerComponent() {
// Data fetching logic may be here
return (
<div>
<h1>Hello, I am a Server Component!</h1>
<p>I don't have any client-side interactivity.</p>
</div>
);
}
Client Component Example:
// This is a Client Component
"use client"
import { useState } from 'react';
export default function ClientComponent() {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<h1>Hello, I am a Client Component!</h1>
<p>I can handle client-side interactivity.</p>
<p>Count: {count}</p>
<button onClick={handleIncrement}>Increment</button>
</div>
);
}
In the example above, the ServerComponent
is a non-interactive component that is primarily rendered on the server-side. It doesn’t use any client-side features like state or event handling.
On the other hand, the ClientComponent
uses the useState
hook to manage state and includes a button to increment the count. This component is pre-rendered on the server, and its interactivity is fully functional on the client-side after hydration.
Project Structure
In terms of file and folder structure, Next.js uses a file-system based router. In the /app
directory:
- Folders are used to define routes. Each folder represents a route segment, and the hierarchy of nested folders corresponds to the hierarchical structure of the routes.
- Files are used to create UI that is shown for a route segment. Next.js provides a set of special files with specific behaviors, such as “layout” for shared UI, “page” for unique UI of a route, “loading” for loading UI, “not-found” for not found UI, and more. These special files can have the extensions .js, .jsx, or .tsx.
![](https://bluesockets.com/wp-content/uploads/2023/07/folder_structure-1024x522.png)
Note: The app
directory must include a root layout (layout.tsx file). This root layout file must define <html>
and <body>
tags because Next.js does not automatically create them.
You have the option to colocate your own files (e.g., components, styles, tests, etc.) inside folders in the “app” directory. However, only the contents returned by the “page.js” or “route.js” files are publicly addressable.
Navigation
The App Router uses server-centric routing with client-side navigation. This means that while the routing is server-centric and aligned with Server Components and data fetching on the server, the navigation is handled on the client-side using the <Link> Component. When a user navigates to a new route, the browser’s URL is updated, and Next.js only renders the segments that change, without reloading the entire page. This provides a smoother user experience and better performance.
2. Streaming
The streaming feature in Next.js 13 allows you to progressively render and incrementally stream rendered units of the UI to the client. With Server Components and nested layouts, you can instantly render parts of the page that don’t require data, providing a better user experience. Users can start interacting with the page without waiting for the entire page to load. Learn more here.
3. Data Fetching
Next.js 13 introduces improved data fetching capabilities. You can now use async Server Components and an extended fetch API to enable component-level fetching. React’s recent Support for Promises RFC is leveraged to fetch and handle data inside components. The native fetch API in React and Next.js automatically dedupes requests and provides a flexible way to fetch, cache, and revalidate data at the component level.
Here is an example from the Next.js team:
async function getData() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
return res.json();
}
// This is an async Server Component
export default async function Page() {
const data = await getData();
return <main>{/* ... */}</main>;
}
4. Turbopack
Next.js 13 includes Turbopack, a Rust-based successor to Webpack. Turbopack offers significantly faster performance compared to Webpack, resulting in faster updates and cold starts. It has out-of-the-box support for Server Components, TypeScript, JSX, CSS, and more. Although Turbopack is currently in beta, it shows great potential for improving the build and development experience in Next.js. Learn more here.
5. Improved Image Component
Next.js 13 introduces an improved Image component that optimizes image loading and performance. It ships less client-side JavaScript, is easier to style and configure, and provides better accessibility with default alt tags. The Image component aligns with web standards, and its native lazy loading feature enhances performance by avoiding unnecessary hydration. Next.js <Image> Component is the go-to way for loading images in a Next.js application. Learn more here.
6. New Font Component
Next.js 13 introduces the @next/font
package, which provides a convenient way to use fonts with performance and privacy in mind. It automatically optimizes fonts, removes external network requests, and enables automatic self-hosting of font files. The new Font component allows customization of the font loading experience while ensuring great performance and no layout shift. Learn more here.
7. Improved Link Component
The Link component in Next.js 13 has been improved to simplify usage. It no longer requires manually adding an anchor tag (<a>
) as a child. The improved Link component always renders an <a>
tag and allows you to forward props to the underlying tag. This change simplifies the usage of links in Next.js applications.
Conclusion
Next.js 13 brings several powerful features and improvements to enhance your development experience. The app directory, layouts, server components, streaming, data fetching, Turbopack, the improved Image component, the new Font component, and the improved Link component are some of the highlights of this release. Upgrade to Next.js 13 to take advantage of these exciting new features and build dynamic web applications with ease.
To learn more about Next.js 13 view the official release on their blog.