Building a Modern Web Application with Next.js 14

Learn how to build a modern web application using Next.js 14 with Server Components and the App Router

By · · Updated · 3 min read · advanced

Learn how to build a modern, production-ready web application using Next.js 14 with Server Components and the App Router.

Project Setup

Create a new Next.js project:

npx create-next-app@latest my-app --typescript --tailwind --app

Server Components Example

// app/posts/page.tsx
import { Suspense } from 'react';
import { PostList } from '@/components/PostList';
import { LoadingSkeleton } from '@/components/LoadingSkeleton';

async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 } // Revalidate every hour
  });
  
  if (!res.ok) throw new Error('Failed to fetch posts');
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();
  
  return (
    <main className="container mx-auto px-4 py-8">
      <h1 className="text-3xl font-bold mb-6">Latest Posts</h1>
      <Suspense fallback={<LoadingSkeleton />}>
        <PostList initialPosts={posts} />
      </Suspense>
    </main>
  );
}

Client Components with Server Actions

// components/CommentForm.tsx
'use client';

import { useOptimistic } from 'react';
import { addComment } from '@/actions/comments';

export function CommentForm({ postId }: { postId: string }) {
  const [optimisticComments, addOptimisticComment] = useOptimistic(
    [],
    (state, newComment) => [...state, newComment]
  );

  async function handleSubmit(formData: FormData) {
    const content = formData.get('content') as string;
    
    // Add optimistic comment
    addOptimisticComment({
      id: 'temp-' + Date.now(),
      content,
      createdAt: new Date().toISOString()
    });
    
    // Server action
    await addComment(postId, content);
  }

  return (
    <form action={handleSubmit}>
      <textarea
        name="content"
        className="w-full p-2 border rounded"
        placeholder="Write a comment..."
      />
      <button
        type="submit"
        className="px-4 py-2 bg-blue-500 text-white rounded"
      >
        Add Comment
      </button>
    </form>
  );
}