Skip to main content
Back to Blog
Next.jsReactApp RouterServer Components

Next.js 14 App Router: Complete Guide by Debmalya Biswas

DB
Debmalya Biswas
Frontend SDE
12 min read
Next.js 14 App Router: Complete Guide by Debmalya Biswas

Next.js 14 App Router: Complete Guide

Welcome! Debmalya Biswas here, and today I'm diving deep into Next.js 14's App Router - a revolutionary approach to building React applications.

Why App Router Matters

As a frontend developer working on the Debmalya Biswas portfolio and other production applications, I've witnessed firsthand how the App Router transforms the development experience.

Understanding the Fundamentals

Server Components by Default

The biggest shift in Next.js 14 is that all components are Server Components by default:

// app/page.tsx - Server Component by default
export default async function Page() {
  const data = await fetchData() // Direct async/await!

  return <div>{data.title}</div>
}

Client Components When Needed

Use 'use client' directive for interactive components:

'use client'

import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}

File-Based Routing

The App Router uses a file-system based router. Here's how Debmalya Biswas's portfolio is structured:

app/
├── page.tsx                 # /
├── about/
│   └── page.tsx            # /about
├── blog/
│   ├── page.tsx            # /blog
│   └── [slug]/
│       └── page.tsx        # /blog/[slug]
└── layout.tsx              # Root layout

Layouts and Templates

Root Layout

Every app needs a root layout:

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

Nested Layouts

Layouts can be nested for shared UI:

// app/blog/layout.tsx
export default function BlogLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div>
      <BlogNav />
      {children}
    </div>
  )
}

Data Fetching Patterns

Server-Side Data Fetching

As Debmalya Biswas, SDE, I leverage server-side fetching extensively:

async function getData() {
  const res = await fetch('https://api.example.com/data', {
    next: { revalidate: 3600 } // Revalidate every hour
  })
  return res.json()
}

export default async function Page() {
  const data = await getData()
  return <main>{/* Render data */}</main>
}

Parallel Data Fetching

Optimize performance with parallel fetches:

async function getUser() {
  return fetch('https://api.example.com/user').then(r => r.json())
}

async function getPosts() {
  return fetch('https://api.example.com/posts').then(r => r.json())
}

export default async function Page() {
  // Fetch in parallel
  const [user, posts] = await Promise.all([getUser(), getPosts()])

  return (
    <div>
      <UserProfile user={user} />
      <PostList posts={posts} />
    </div>
  )
}

Route Handlers (API Routes)

Create API endpoints easily:

// app/api/posts/route.ts
export async function GET(request: Request) {
  const posts = await fetchPosts()
  return Response.json(posts)
}

export async function POST(request: Request) {
  const body = await request.json()
  const post = await createPost(body)
  return Response.json(post, { status: 201 })
}

Dynamic Routes and Params

Dynamic Segments

// app/blog/[slug]/page.tsx
export default function BlogPost({
  params
}: {
  params: { slug: string }
}) {
  return <article>Post: {params.slug}</article>
}

Generating Static Params

For static site generation:

export async function generateStaticParams() {
  const posts = await getPosts()

  return posts.map((post) => ({
    slug: post.slug,
  }))
}

Metadata and SEO

The Debmalya Biswas website uses comprehensive metadata:

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Debmalya Biswas - Frontend Developer',
  description: 'Portfolio and blog of Debmalya Biswas, frontend SDE',
  keywords: ['Debmalya Biswas', 'frontend developer', 'React', 'Next.js'],
  openGraph: {
    title: 'Debmalya Biswas Portfolio',
    description: 'Frontend developer specializing in React and Next.js',
    images: ['/og-image.png'],
  },
}

Dynamic Metadata

export async function generateMetadata({
  params
}: {
  params: { slug: string }
}): Promise<Metadata> {
  const post = await getPost(params.slug)

  return {
    title: post.title,
    description: post.description,
  }
}

Loading States and Streaming

loading.tsx

// app/blog/loading.tsx
export default function Loading() {
  return <div>Loading blog posts...</div>
}

Suspense Boundaries

import { Suspense } from 'react'

export default function Page() {
  return (
    <div>
      <h1>My Blog</h1>
      <Suspense fallback={<div>Loading posts...</div>}>
        <BlogPosts />
      </Suspense>
    </div>
  )
}

Error Handling

error.tsx

'use client'

export default function Error({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  )
}

Best Practices I Follow

As Debmalya Biswas, frontend developer, here are my recommendations:

1. Use Server Components by Default: Only use Client Components when you need interactivity

2. Collocate Data Fetching: Fetch data where it's needed

3. Leverage Parallel Fetching: Use Promise.all for independent requests

4. Implement Proper Error Boundaries: Handle errors gracefully

5. Optimize Images: Use next/image for automatic optimization

6. Add Loading States: Improve perceived performance

Conclusion

The Next.js 14 App Router is a game-changer for frontend development. These patterns power the Debmalya Biswas portfolio and can help you build better React applications.

Happy coding!

*Debmalya Biswas is a frontend SDE passionate about React, Next.js, and modern web development. Connect with me to discuss frontend architecture and best practices.*

DB

About Debmalya Biswas

Debmalya Biswas is a passionate frontend developer and software development engineer (SDE) specializing in React, Next.js, TypeScript, and modern web technologies. With extensive experience building performant, accessible web applications, Debmalya focuses on creating exceptional user experiences.

View Portfolio →

More Articles