The Next.js Compiler

Next.js uses SWC, a super-performant compilation and bundling platform for JavaScript/TypeScript written in Rust.

App Router & Server Components

Next.js 13 introduced the app router building on top of React Server Components. Components inside the app folder are Server Components by default. This approach agrees with the server-first approach React advocates. It makes data fetching simpler and more secure.

Next.js uses React’s API to render on the server in a two-step process, splitting code into chunks by router segments and React.Suspense boundaries. The first step is rendering Server Components into React Server Component Payload. Step two involves using RSC Payload and Client Component JavaScript instructions to render HTML on the server. This means we don’t have to wait for the entire render to complete before caching or sending a response. Instead, we can start streaming a response as the rendering is carried out.

Next.js app router is file-based, meaning you can use folders to construct URL paths. One caveat is that Next reserves specific file names, including layout, page, loading, not-found, error, global-error, route, template and default.

Next allows you to colocate your private files inside the app folder. For example, you can put your CSS files or React components next to your page.js/jsx/tsx. By default, only contents returned by page.js/jsx/tsx or route.js are publicly addressable. The rest are private by default.

Although the new routing system is server-centric, it still uses client-side navigation through the next/Link component.

Layouts

A layout is the UI template that can be shared among many pages. It can store state, maintain page interactivity and avoid full page reload.

// ./app/layout.tsx
 
export default function DefautLayout({ 
  children, // will be a page or nested layout
}: { children: React.ReactNode }) { 
  return ( 
    <section> 
    { /* Include shared UI here e.g. a header or sidebar */} 
      <nav></nav>
      {children}
    </section> 
  )
}

Layouts defined along the navigation path (URL segments) will be nested. They wrap child layouts through the {childen} prop. Layouts are applied automatically by Next.js; uses don’t need to configure them manually.

// ./app/ai/layout.tsx
 
export default function AILayout({ 
  children,
}: { children: React.ReactNode}) { 
  return (
	<section>
	  {children}
    </section>
  );
}

Root Layout

Every Next.js app must have a root layout to be shared among all the pages. The root layout must include the <html> and <body> tags.

// ./app/layout.tsx
 
export default function RootLayout({ 
  children,
}: { children: React.ReactNode}) { 
  return ( 
    <html lang="en"><body>{children}</body></html> 
  );
}

Templates

Templates organise UI concerns in a similar way to layouts. The main difference is that templates do not preserve the app state. When a navigation event happens, all components inside a template will be re-rendered with a fresh state.

// ./app/ai/template.tsx
 
export default function Template({ 
  children 
}: { children: React.ReactNode }) { 
  return <div>{children}</div>
}

Templates can be used in conjunction with layouts. The rendered output of a route segment with a layout and a template follow the below hierarchy.

<Layout> 
  {/* Note that the template is given a unique key. */} 
  <Template key={routeParam}>{children}</Template>
</Layout>

SSR, SSG & CSR

Next.js supports two pre-rendering methods: Server-Side Rendering (SSR), Server-Side Generation (SSG), and the traditional React Client-Side Rendering (CSR). You can configure which rendering method to use on a per-page basis.