Next.js 14 App Router: The Complete Developer's Guide
Frontend

Next.js 14 App Router: The Complete Developer's Guide

M

Md Nayeem Hossain

Author

Dec 25, 2024
12 min read

Next.js 14 App Router: Complete Guide

Next.js 14 marks a significant shift in how we build React applications. The introduction of the App Router is not just a routing update; it's a fundamental change in architecture that leverages React Server Components (RSC).

Why Server Components Matter

Traditionally, React rendered everything on the client (or hydrated everything). This meant sending a lot of JavaScript to the browser, which could be slow.

Server Components allow us to render components *exclusively* on the server. The HTML is generated, but no JavaScript is sent to the client for that component. This results in faster initial page loads and smaller bundle sizes.

Here is an example of a Server Component fetching data directly from a database. Notice there is no useEffect or API call—it just runs on the server!

tsx
// app/users/page.tsx - Server Component by default
import { db } from '@/lib/db';

async function UsersPage() {
  // Direct database access is safe here because this code ONLY runs on the server
  const users = await db.user.findMany();
  
  return (
    <div>
      <h1>Users List</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default UsersPage;

When to use "use client"

You can't do everything on the server. If you need user interaction—like clicking a button, using useState, or listening to window events—you need a Client Component.

You mark a component as a Client Component by adding the "use client" directive at the top of the file.

tsx
"use client"

import { useState } from 'react';

export default function Counter() {
  // We can use state here because of "use client"
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count is {count}
    </button>
  );
}

Server Actions: Goodbye API Routes?

Next.js 14 introduces Server Actions, which allow you to invoke server-side functions directly from client components. This simplifies form handling and data mutations immensely. You often don't even need to create a separate API route anymore.

tsx
// app/actions.ts
"use server"

import { db } from '@/lib/db';
import { revalidatePath } from 'next/cache';

export async function createUser(formData: FormData) {
  const name = formData.get('name');
  
  await db.user.create({ data: { name } });
  
  // This tells Next.js to refresh the data on the /users page
  revalidatePath('/users');
}

Then you can use this action simply as the action prop in a form:

tsx
// app/users/new/page.tsx
import { createUser } from '../actions';

export default function NewUserForm() {
  return (
    <form action={createUser}>
      <input name="name" type="text" />
      <button type="submit">Add User</button>
    </form>
  );
}

This pattern significantly reduces the amount of "glue code" you need to write to connect your frontend to your backend.

Next.js
React
SSR
Server Components

© 2026 Md Nayeem Hossain. All rights reserved.