Why App Router?
Server Components are the biggest advantage of App Router. They allow you to render components on the server, reducing the JavaScript bundle sent to the client and improving initial load times.
Key Benefits
Folder Structure
Organize your App Router project with these conventions:
app/
├── layout.tsx # Root layout
├── page.tsx # Home page
├── globals.css # Global styles
├── (marketing)/ # Route group
│ └── about/
│ └── page.tsx
├── blog/
│ ├── page.tsx # Blog listing
│ └── [slug]/
│ └── page.tsx # Dynamic blog posts
└── api/
└── route.ts # API routes
Best Practices
1. Use Server Components Whenever Possible
// ✅ Good: Server Component
async function BlogPost({ slug }: { slug: string }) {
const post = await getPost(slug);
return <article>{post.content}</article>;
}
// ❌ Avoid: Client Component unless needed
'use client';
function BlogPost({ slug }: { slug: string }) {
// Only use client components for interactivity
}
2. Implement Proper Metadata
export const metadata: Metadata = {
title: {
template: '%s | My App',
default: 'My App',
},
description: 'Description here',
openGraph: {
title: 'Title',
description: 'Description',
images: ['/og-image.jpg'],
},
};
3. Use Loading and Error Boundaries
// app/blog/loading.tsx
export default function Loading() {
return <Skeleton />;
}
// app/blog/error.tsx
'use client';
export default function Error({ reset }) {
return (
<div>
<p>Something went wrong!</p>
<button onClick={reset}>Try again</button>
</div>
);
}
Conclusion
The App Router is the future of Next.js development. By following these best practices, you'll build faster, more maintainable applications that scale well.
app/
├── layout.tsx # Root layout
├── page.tsx # Home page
├── globals.css # Global styles
├── (marketing)/ # Route group
│ └── about/
│ └── page.tsx
├── blog/
│ ├── page.tsx # Blog listing
│ └── [slug]/
│ └── page.tsx # Dynamic blog posts
└── api/
└── route.ts # API routes
// ✅ Good: Server Component
async function BlogPost({ slug }: { slug: string }) {
const post = await getPost(slug);
return <article>{post.content}</article>;
}
// ❌ Avoid: Client Component unless needed
'use client';
function BlogPost({ slug }: { slug: string }) {
// Only use client components for interactivity
}
export const metadata: Metadata = {
title: {
template: '%s | My App',
default: 'My App',
},
description: 'Description here',
openGraph: {
title: 'Title',
description: 'Description',
images: ['/og-image.jpg'],
},
};
// app/blog/loading.tsx
export default function Loading() {
return <Skeleton />;
}
// app/blog/error.tsx
'use client';
export default function Error({ reset }) {
return (
<div>
<p>Something went wrong!</p>
<button onClick={reset}>Try again</button>
</div>
);
}