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 Ajith joseph · · 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>
);
}