App Router

Introduction

  • App router is mixture of multiple page and single page application

  • Each path has their own html page but when using next/link, the javascript will be loaded instead of html file

  • The initial page will be rendered on server, but for user interaction (e.g: useState, useEffect) , the page is needed to be hydrated with javascript file

Server & Client Side Component

  • When html page of Nextjs is loaded, the static content and data of of server component will be pre-rendered and fetched

  • The data of client component will then be hydrated through built javascript file

Example

layout.tsx
"use client";
// import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";

const geistSans = localFont({
  src: "./fonts/GeistVF.woff",
  variable: "--font-geist-sans",
  weight: "100 900",
});
const geistMono = localFont({
  src: "./fonts/GeistMonoVF.woff",
  variable: "--font-geist-mono",
  weight: "100 900",
});

// export const metadata: Metadata = {
//   title: "Create Next App",
//   description: "Generated by create next app",
// };
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        client layout
        {children}
      </body>
    </html>
  );
}

Result

The pre-rendered html page
The hydrated html page
Result of fetching RSC payload
  • If using Link instead of a tag for navigation. On UI level, it will be shown as a tag, but it will execute client side navigation behind the scene,

  • If the page contains server component, only RSC payload will be fetched, which is the result of server-side rendering and the position of client-side component with corresponding javascript file

Backend API

  • Nextjs can be used to act as full stack development, here is the example of implementing backend part. The file must be route.ts/js

Caching

  • When using fetch api on Nextjs, there are several caches existing - request memoization, data cache

Request memoization

  • If you need to use the same data across a route, e.g using the same component, you do not have to fetch data in every time. Instead, it will fetch data once.

  • The cache lasts the lifetime of a server request until the React component tree has finished rendering.

Result
  • To disable request memoization, we need integrate with AbortController

After disabling

Data Cache

  • If fetch data with caching, the page will be built as static content (Static Generation), otherwise, the page will be built as dynamic

Cache options

  • Configure how the request should interact with Next.js Data Cache.

  • default: Nextjs fetching will be treated same as force-cache, unless revaildate is specified

  • no-store: Next.js fetches the resource from the remote server on every request without looking in the cache, and it will not update the cache with the downloaded resource.

  • force-cache: Next.js looks for a matching request in its Data Cache.

    • If there is a match and it is fresh, it will be returned from the cache.

    • If there is no match or a stale match, Next.js will fetch the resource from the remote server and update the cache with the downloaded resource.

Incremental Static Regeneration (ISR)

  • The data of cache will be stale after a period of time, and the data will be obtained from data source rather than cache

Layout

  • The component in the layout file can be shared in the same directory and its nested page file

  • SideMenu is common use case to put it into layout file

Not Found & Error Boundary Page

  • Error page must be client component

Route Folder & File naming

  • (Folder name) can be used without affecting the path

  • page.tsx refer to the page

  • [slug] refer to dynamic page

Loading

  • The data fetching support Suspense of react

Parallel Route

  • Parallel Routes allows you to simultaneously or conditionally render one or more pages within the same layout.

  • Each route can actually be treated as component on layout

  • Each route nested route pattern must be the same

Last updated

Was this helpful?