Next.js 14 App Router Expert
Expert in Next.js 14 App Router, React Server Components, and modern web development
# Next.js 14 App Router Best Practices
Ultimate guide for building production-ready applications with Next.js 14 App Router, React Server Components, and modern web development patterns.
---
## Core Principles
1. **Server-First Architecture**
- Use React Server Components by default for better performance
- Only add `'use client'` directive when absolutely necessary (user interactions, browser APIs)
- Fetch data directly in server components instead of client-side useEffect patterns
2. **App Directory Structure**
- Leverage the new `app/` directory structure over legacy `pages/`
- Use `page.tsx` for route components and `layout.tsx` for shared layouts
- Example structure:
```
app/
layout.tsx // Root layout
page.tsx // Home page
dashboard/
layout.tsx // Dashboard layout
page.tsx // Dashboard page
settings/
page.tsx // Settings page
```
3. **TypeScript Integration**
- Use strict TypeScript configuration for better type safety
- Define proper types for route parameters, search params, and props
- Example:
```ts
interface PageProps {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
}
```
---
## Data Fetching Patterns
4. **Server Component Data Fetching**
- Fetch data directly in server components using async/await
- No need for useState or useEffect for initial data loading
- Example:
```tsx
async function ProductPage({ params }: { params: { id: string } }) {
const product = await fetch(`/api/products/${params.id}`).then(r => r.json());
return <ProductDisplay product={product} />;
}
```
5. **Parallel Data Fetching**
- Use Promise.all() to fetch multiple data sources simultaneously
- Prevents waterfall requests and improves performance
- Example:
```tsx
async function Dashboard() {
const [user, posts, analytics] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchAnalytics()
]);
return <DashboardView user={user} posts={posts} analytics={analytics} />;
}
```
6. **Client-Side Data Fetching**
- Use SWR or React Query for client-side data fetching when needed
- Implement proper loading and error states
- Only use for user-triggered actions or real-time updates
---
## Routing and Navigation
7. **Dynamic Routes**
- Use `[param]` for dynamic segments and `[...slug]` for catch-all routes
- Access route parameters through the `params` prop
- Example: `app/blog/[slug]/page.tsx`
8. **Route Groups and Layouts**
- Use `(groupName)` for organizing routes without affecting URL structure
- Create targeted layouts for specific route groups
- Example: `app/(dashboard)/analytics/page.tsx`
9. **Programmatic Navigation**
- Use `useRouter` from `next/navigation` (not `next/router`)
- Prefer `router.push()` over `router.replace()` for better UX
- Example:
```tsx
'use client';
import { useRouter } from 'next/navigation';
function NavigateButton() {
const router = useRouter();
return <button onClick={() => router.push('/dashboard')}>Go to Dashboard</button>;
}
```
---
## Special Files and Conventions
10. **Loading UI**
- Create `loading.tsx` files for instant loading states
- Use loading boundaries to show progressive loading
- Implement skeleton components for better perceived performance
11. **Error Handling**
- Use `error.tsx` files for error boundaries at route level
- Implement `not-found.tsx` for custom 404 pages
- Add proper error recovery mechanisms
12. **Route Handlers (API Routes)**
- Create API endpoints using `route.ts` files in app directory
- Support multiple HTTP methods in a single file
- Example:
```ts
// app/api/users/route.ts
export async function GET() {
return Response.json({ users: [] });
}
export async function POST(request: Request) {
const data = await request.json();
return Response.json({ success: true });
}
```
---
## Performance Optimization
13. **Image Optimization**
- Always use `next/image` component instead of HTML `<img>`
- Implement proper `alt` attributes and sizing
- Use `priority` prop for above-the-fold images
- Example:
```tsx
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
priority
/>
```
14. **Code Splitting and Dynamic Imports**
- Use dynamic imports for heavy components or libraries
- Implement proper loading states for dynamically imported components
- Example:
```tsx
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <p>Loading chart...</p>
});
```
15. **Caching Strategies**
- Leverage Next.js automatic caching for fetch requests
- Use `revalidate` option for ISR (Incremental Static Regeneration)
- Implement proper cache invalidation strategies
- Example:
```ts
fetch('/api/data', { next: { revalidate: 3600 } }); // Cache for 1 hour
```
---
## State Management
16. **Server State vs Client State**
- Keep server state on the server (in server components)
- Use client state only for UI-specific state (modals, form inputs)
- Consider React Context or Zustand for complex client state
17. **Form Handling**
- Use Server Actions for form submissions when possible
- Implement proper form validation and error handling
- Example:
```tsx
async function createUser(formData: FormData) {
'use server';
const name = formData.get('name');
// Handle form submission
}
function UserForm() {
return (
<form action={createUser}>
<input name="name" required />
<button type="submit">Create User</button>
</form>
);
}
```
---
## Security and Best Practices
18. **Environment Variables**
- Use `NEXT_PUBLIC_` prefix for client-side environment variables
- Keep sensitive data server-side only
- Validate environment variables at build time
19. **Content Security Policy**
- Implement proper CSP headers for security
- Use nonce-based CSP for inline scripts and styles
- Configure CSP in `next.config.js`
20. **SEO and Metadata**
- Use the new Metadata API for better SEO
- Implement proper Open Graph and Twitter Card meta tags
- Example:
```ts
export const metadata = {
title: 'My App',
description: 'Description of my app',
openGraph: {
title: 'My App',
description: 'Description of my app',
images: ['/og-image.jpg']
}
};
```
---
## Testing
21. **Component Testing**
- Test server components by testing their data fetching logic
- Use React Testing Library for client component testing
- Mock external API calls appropriately
22. **E2E Testing**
- Use Playwright or Cypress for end-to-end testing
- Test critical user journeys and form submissions
- Implement visual regression testing for UI consistency
---
## Summary Checklist
- [ ] Use server components by default, client components only when needed
- [ ] Implement proper app directory structure with layouts
- [ ] Fetch data in server components, not useEffect
- [ ] Use loading.tsx and error.tsx for better UX
- [ ] Optimize images with next/image component
- [ ] Implement proper TypeScript types for routes
- [ ] Use Server Actions for form handling
- [ ] Leverage Next.js caching strategies
- [ ] Implement proper SEO with Metadata API
- [ ] Test both server and client components appropriately
---
Follow these patterns to build scalable, performant, and maintainable Next.js 14 applications.