BackBlog
Jun 28, 20268 min read

Modern Frontend with Next.js App Router

Next.js
React
TypeScript
React code on screen

Next.js 13+ introduced the App Router, fundamentally changing how we think about routing and rendering in React applications. Server Components, streaming, and nested layouts are now first-class citizens.

Server Components by Default

In the App Router, every component is a Server Component unless you explicitly opt into client-side rendering with the 'use client' directive. This means your components run on the server, reducing the JavaScript bundle sent to the browser.

// This runs on the server - no JS sent to client
async function BlogList() {
  const posts = await db.post.findMany();
  return posts.map(post => <PostCard key={post.id} {...post} />);
}

Streaming with Suspense

One of the most powerful features is streaming. You can show content progressively as it becomes available, rather than waiting for the entire page to load.

import { Suspense } from 'react';

export default function Page() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<StatsSkeleton />}>
        <Stats />
      </Suspense>
      <Suspense fallback={<ChartSkeleton />}>
        <RevenueChart />
      </Suspense>
    </div>
  );
}

Layouts and Templates

The App Router introduces shared layouts that persist across navigations. This means your sidebar or header doesn't re-render when navigating between pages.

When to Use Client Components

Not everything should be a Server Component. Use Client Components when you need interactivity (useState, useEffect, event handlers), browser APIs (localStorage, geolocation), or certain third-party libraries.

Key Takeaways

- Default to Server Components — they're faster and lighter

- Use Suspense boundaries for better UX

- Layouts persist — design your component tree accordingly

- The 'use client' boundary is your tool for interactivity