Skip to main content
avatarJay Patel

Getting Started with Next.js App Router

A practical guide to building modern web applications with Next.js App Router, Server Components, and the latest React patterns.

Posted Jul 20, 20253 min readWeb Development

Why Next.js App Router?

The App Router introduced in Next.js 13 represents a fundamental shift in how we build React applications. Instead of the traditional pages directory, we now have a file-system based router built on top of React Server Components.

Key advantages include:

  • Server Components by default — less JavaScript shipped to the client
  • Nested layouts that persist across navigations
  • Streaming with loading UI and Suspense boundaries
  • Built-in data fetching without useEffect or external libraries

Project Setup

Getting started is straightforward:

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

This scaffolds a project with TypeScript, Tailwind CSS, and the App Router enabled out of the box.

Understanding the File Conventions

The App Router uses special file names to define UI:

FilePurpose
layout.tsxShared UI that wraps child routes
page.tsxUnique UI for a route
loading.tsxLoading state with Suspense
error.tsxError boundary for a segment
not-found.tsx404 UI for a segment

Server vs Client Components

By default, every component in the App Router is a Server Component. This means it runs on the server and sends only HTML to the browser.

When you need interactivity, add the "use client" directive:

"use client";
 
import { useState } from "react";
 
export function Counter() {
  const [count, setCount] = useState(0);
 
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

Rule of thumb: Keep components on the server unless they need browser APIs, event handlers, or React state.

Data Fetching

One of the biggest improvements is how data fetching works. Server Components can be async:

async function BlogPosts() {
  const posts = await db.post.findMany({
    orderBy: { createdAt: "desc" },
  });
 
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

No useEffect. No loading state management. No client-side fetching library. The data is fetched on the server and streamed to the client as HTML.

Dynamic Routes

Dynamic segments use bracket notation in folder names:

app/blog/[slug]/page.tsx

Combined with generateStaticParams, you get static generation for known paths:

export function generateStaticParams() {
  return [
    { slug: "hello-world" },
    { slug: "getting-started" },
  ];
}

Conclusion

The App Router is a major step forward for React development. Server Components reduce bundle sizes, nested layouts eliminate redundant re-renders, and the file-based conventions make routing intuitive. If you're starting a new project today, the App Router is the way to go.

#nextjs#react#typescript#server-components

Licensed under CC BY 4.0

Share: