What You Need to Know About Next.js 13

Share with a friend:

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

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.

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.

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.

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.

Share with a friend:

Rajae Robinson

Rajae Robinson is a young Software Developer with over 3 years of work experience building websites and mobile apps. He has extensive experience with React.js and Next.js.

Recent Posts