8 min read

Next.js 2023: App Directory, Server Components - A Giant Leap!

Next.js 2023: App Directory, Server Components - A Giant Leap!

Next.js 2023: Not Just an “Update”, but a “Revolution”!

“Hey everyone!” 👋 2023 marks a major turning point for Next.js with the introduction of the App Directory (Beta), React Server Components, and new data fetching features. These changes are not just simple “updates”; they are a true “revolution,” changing the way we build web apps. In this post, let’s “unbox” these fresh features and see how awesome they really are!

1. The Context Before the 2023 Release

Before 2023, building web applications with Next.js was already fantastic: we had SSR, SSG, and Automatic Routing—powerful features that helped create fast, interactive, and SEO-friendly websites. Even with all this, Next.js wasn’t sitting idle, constantly pushing for innovation. This is the strength of a framework that “leads” the web development world.

2. The Highlight Features of 2023

App Directory (Beta): “Rebuilding” the Project Structure! 💥

As mentioned in our 2022 article, let’s revisit and examine the changes to the App Directory in 2023. The phrase ‘Rebuild’ may sound daunting, but it actually represents a significant advancement for Next.js. The App Directory (currently in Beta) offers a new and more flexible way to organize code, which is more modern and sophisticated compared to the traditional pages directory.

The standout features of the App Directory:

  • Layouts: Easily define common layouts for routes, reducing code duplication.
  • Server Components: Render components on the server, offloading work from the client, “speeding up” page loads.
  • Streaming: Stream data more smoothly, improving the user experience.
  • Colocation: Place code, styles, and tests right next to components, making it cleaner and easier to manage.

Example directory structure:

app/
├── about/
│   ├── page.tsx      // /about
│   └── layout.tsx   // Layout for /about
├── dashboard/
│   ├── settings/
│   │   └── page.tsx  // /dashboard/settings
│   ├── analytics
│   │   └── page.tsx  // /dashboard/analytics
│   └── layout.tsx   // Layout for /dashboard
├── (marketing)/
│   ├── layout.tsx   // Layout for marketing group
│   ├── layout.tsx
│   └── page.tsx      // / (home page)
├── (shop)/
│   ├── cart/
│   │   └── page.tsx  // /(shop)/cart
│   └── layout.tsx   // Layout for shop group
├── components        // Shared components
├── lib               // Utility functions
└── types             // Type definitions

Using Layouts:

// app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div>
      <h1>Dashboard</h1>
      {/* Sidebar, header, etc. */}
      <section>{children}</section>
    </div>
  );
}
3.1 APP DIRECTORY: “Direct Serving?”

The benefit of the App Directory is not just in code organization but also in how it enhances performance, making the code run more efficiently. With the Layout function, it helps build parts of the website without repeating code, saving time and effort like never before.

3.2 SERVER COMPONENTS: “Run On The Server”

Server Components reduce the client load by rendering part of the UI on the server, significantly improving performance. This feature opens up new possibilities, like accessing databases directly from the server without needing an API. As a result, data is fetched more efficiently, reducing response time and improving the user experience.

React Server Components: “Server-Side” Right Inside the Component! 🤯

This is a major breakthrough in the React community. Server Components allow you to render a component directly on the server, reducing the amount of JavaScript that needs to be downloaded to the client, thereby significantly boosting performance.

Benefits:

  • Smaller bundle size: Eliminates unnecessary code from the client bundle.
  • Direct access to back-end resources: Fetch data directly from a database, file system, microservices, etc., without going through an API.
  • Better security: Keep sensitive logic (like API keys) on the server side.

Example:

// app/components/ProductList.tsx (Server Component)
import { db } from "@/lib/db"; // Access database directly, no API needed
export default async function ProductList() {
  const products = await db.query("SELECT * FROM products"); // Direct query from database
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Note: Server Components are still in experimental stages. One of the initial challenges when using Server Components is the limited complexity of code that can run on the server, so careful decision-making regarding responsibilities between the server and client is crucial.

4.1 Server Components: “A Jungle of Possibilities”

One of the major strengths of Server Components is its ability to handle complex tasks without overloading the client. Using the server for tasks like data processing, rendering complex layouts, or handling real-time operations reduces the workload for the client, improving overall performance.

4.2 FROM CLIENT-SIDE TO SERVER-SIDE

Switching from rendering components entirely on the client side to partially handling it on the server helps avoid loading the entire app, reducing the size of the file sent to the client, thus increasing page load speed and enhancing the user experience.

Data Fetching: “All in One” with fetch

Next.js 2023 upgrades the fetch API with new features:

  • Automatic Request Deduplication: Prevents duplicate data fetching.
  • Data Caching: Automatically caches data, speeding up page loads.
  • Revalidation: Flexibly updates data (similar to ISR).
  • Streaming: Streams data as it becomes available, without waiting for the entire server response.

Example:

// app/page.tsx
async function getProducts() {
  const res = await fetch("https://.../products", { next: { revalidate: 60 } });
  return res.json();
}
export default async function Page() {
  const products = await getProducts();
  return (
    <ul>
      {products.map((product) => {
        return (
          <li key={product.id}>
            <h3>{product.name}</h3>
          </li>
        );
      })}
    </ul>
  );
}
5.1 Automatic Request Deduplication: “Just As I Expected!”

Automatic Request Deduplication reduces unnecessary processing, preventing duplicate data requests. This not only optimizes performance but also reduces server load.

5.2 Data Caching: Smarter Than Ever

Another notable feature is automatic data caching. This reduces the workload each time the page is accessed, thereby improving both performance and user experience.

5.3 Data Updates: Flexibility and Precision!

The flexible data update feature using revalidate ensures that your data is always up to date without worrying about synchronization.

3. Setting Up a Next.js 2023 Project: “Welcome” App Directory!

To create a Next.js project with the App Directory, run:

npx create-next-app@latest my-next-app --experimental-app
cd my-next-app
npm run dev

Just like that, you have a project using the App Directory. During setup, necessary directory structures and files will be automatically generated, making the work easier.

4. Some Other Updated Features

4.1 Route Group

Route Group allows you to group routes together, defining separate areas for specific functionality groups. This feature helps organize the code better, making it easier to maintain and expand the app.

Example directory structure:

app/
├── (marketing)/
│   ├── layout.tsx     // Define layout for marketing
│   ├── page.tsx       // Main marketing page
│   └── about.tsx      // Marketing about page
└── (shop)/
    ├── layout.tsx     // Define layout for shop
    ├── page.tsx       // Main shop page
    └── product.tsx    // Product details page

4.2 Client Component: A New Performance Boost

The addition of Client Components enhances the ability to handle client-side tasks more efficiently. Client Components, combined with Server Components, provide a complete approach to workload distribution between the server and client, optimizing app performance.

Example:

// app/components/ProductDetail.tsx (Client Component)
"use client";

import { useState, useEffect } from "react";

export default function ProductDetail({ productId }) {
  const [product, setProduct] = useState(null);

  useEffect(() => {
    // Call API to fetch product details
    fetch(`/api/products/${productId}`)
      .then((res) => res.json())
      .then((data) => setProduct(data));
  }, [productId]);

  if (!product) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </div>
  );
}

5. Conclusion: Next.js is “Better Than Ever”!

Next.js 2023 is truly a “giant leap” with the App Directory, React Server Components, and new data fetching. These improvements make web app development smoother, more efficient, and “cooler” than ever before. Upgrade to Next.js now and experience these “top-notch” features!

6. Additional Resources

These major improvements are sure to grab the attention of the development community. For a more in-depth understanding of the new features in Next.js 2023, check out the following resources:

Wishing you all a relaxing and meaningful summer! 🎉🌞