# Advanced Next.js: Building Scalable Applications
This article explores advanced patterns and techniques for building large-scale applications with Next.js.
## Advanced Routing Patterns
### Parallel Routes
“`typescript
// app/@modal/login/page.tsx
export default function LoginModal() {
return (
<div className=”modal”>
<h2>Login</h2>
<form>
{/* Login form fields */}
</form>
</div>
);
}
// app/layout.tsx
export default function RootLayout({
children,
modal,
}: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
“`
### Intercepting Routes
“`typescript
// app/posts/[id]/@modal/(.)edit/page.tsx
export default function EditPostModal({
params,
}: {
params: { id: string };
}) {
return (
<div className=”modal”>
<h2>Edit Post {params.id}</h2>
<PostForm id={params.id} />
</div>
);
}
“`
## Advanced State Management
### Server Actions with Optimistic Updates
“`typescript
‘use client’;
import { experimental_useOptimistic as useOptimistic } from ‘react’;
export default function TodoList({ initialTodos }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
initialTodos,
(state, newTodo) => […state, newTodo]
);
async function addTodo(formData: FormData) {
const todo = {
id: Math.random(),
text: formData.get(‘todo’),
completed: false,
};
addOptimisticTodo(todo);
await fetch(‘/api/todos’, {
method: ‘POST’,
body: JSON.stringify(todo),
});
}
return (
<div>
<form action={addTodo}>
<input name=”todo” />
<button type=”submit”>Add Todo</button>
</form>
<ul>
{optimisticTodos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}
“`
## Advanced Data Fetching
### Streaming with Suspense
“`typescript
// app/posts/page.tsx
import { Suspense } from ‘react’;
import PostList from ‘./PostList’;
import SkeletonList from ‘./SkeletonList’;
export default function PostsPage() {
return (
<div>
<h1>Posts</h1>
<Suspense fallback={<SkeletonList />}>
<PostList />
</Suspense>
</div>
);
}
// app/posts/PostList.tsx
async function PostList() {
const posts = await fetchPostsSlowly();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
“`
### Parallel Data Fetching
“`typescript
// utils/fetch.ts
async function fetchPosts() {
const res = await fetch(‘https://api.example.com/posts’);
return res.json();
}
async function fetchUser(id: string) {
const res = await fetch(`https://api.example.com/users/${id}`);
return res.json();
}
// app/dashboard/page.tsx
export default async function Dashboard() {
const [posts, user] = await Promise.all([
fetchPosts(),
fetchUser(‘current’),
]);
return (
<div>
<UserProfile user={user} />
<PostList posts={posts} />
</div>
);
}
“`
## Custom Server-Side Rendering
### Dynamic Rendering Decisions
“`typescript
// app/posts/[id]/page.tsx
import { headers } from ‘next/headers’;
import { redirect } from ‘next/navigation’;
export default async function Post({
params,
}: {
params: { id: string };
}) {
const headersList = headers();
const userAgent = headersList.get(‘user-agent’);
// Dynamic rendering decision
if (userAgent?.includes(‘Googlebot’)) {
// Render differently for search engines
return <StaticPostVersion id={params.id} />;
}
// Regular rendering
return <DynamicPostVersion id={params.id} />;
}
“`
## Advanced Caching Strategies
### Revalidation Patterns
“`typescript
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from ‘next/cache’;
import { NextResponse } from ‘next/server’;
export async function POST(request: Request) {
const { path, tag } = await request.json();
if (path) {
revalidatePath(path);
}
if (tag) {
revalidateTag(tag);
}
return NextResponse.json({ revalidated: true });
}
// Usage in data fetching
fetch(‘https://api.example.com/posts’, {
next: {
tags: [‘posts’],
revalidate: 3600,
},
});
“`
## Performance Optimization
### Route Handlers Optimization
“`typescript
// app/api/posts/route.ts
import { NextResponse } from ‘next/server’;
import { headers } from ‘next/headers’;
export async function GET(request: Request) {
const headersList = headers();
const referer = headersList.get(‘referer’);
// Cache configuration
const cacheOptions = {
headers: {
‘Cache-Control’: ‘public, s-maxage=10, stale-while-revalidate=59’,
},
};
try {
const posts = await fetchPosts();
return NextResponse.json(posts, cacheOptions);
} catch (error) {
return NextResponse.json(
{ error: ‘Failed to fetch posts’ },
{ status: 500 }
);
}
}
“`
### Image Optimization Patterns
“`typescript
// components/OptimizedImage.tsx
import Image from ‘next/image’;
export default function OptimizedImage({
src,
alt,
}: {
src: string;
alt: string;
}) {
return (
<div className=”aspect-w-16 aspect-h-9 relative”>
<Image
src={src}
alt={alt}
fill
sizes=”(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
33vw”
className=”object-cover”
loading=”lazy”
/>
</div>
);
}
“`
This article covers advanced Next.js topics, providing developers with sophisticated patterns for building scalable applications.
Would you like me to explain any specific aspect in more detail or cover additional advanced topics?