💡 Key Takeaways
- Directives control rendering, caching, and client/server behavior
'use client' enables client features; 'use server' triggers server actions
- Combine dynamic, static, and fetch cache directives for optimal performance
⚡ Client-Side Directives
Client Component Basics
'use client' must be first line
- Allows hooks and browser APIs
- Use for interactive components
'use client';
import { useState, useEffect } from 'react';
export default function ClientComponent() {
const [count, setCount] = useState(0);
useEffect(() => console.log('Mounted!'), []);
return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>;
}
Server Actions in Client Components
'use server' inside client components
- Allows server actions (database calls, validations)
- Works with
useFormState
'use client';
import { useFormState } from 'react-dom';
async function submitForm(prev, formData) {
'use server';
await saveToDatabase(formData.get('name'));
return { success: true };
}
export default function Form() {
const [state, formAction] = useFormState(submitForm, {});
return (
<form action={formAction}>
<input name="name" required />
<button type="submit">Submit</button>
</form>
);
}
🧩 Rendering Directives
Dynamic Page Rendering
- Control page rendering type
dynamic can be 'force-dynamic', 'force-static', 'auto'
- Use static by default, dynamic when necessary
export const dynamic = 'force-dynamic';
export default function DynamicPage() {
return <div>Rendered on each request</div>;
}
Fetch Cache Control
- Control caching behavior per fetch or route segment
fetchCache can be 'force-cache', 'force-no-store', 'auto'
- Adjust based on data volatility
export const fetchCache = 'force-no-store';
export default async function Page() {
const data = await fetch('https://api.example.com/data');
return <div>{JSON.stringify(await data.json())}</div>;
}
⏱️ Revalidation Directives
ISR Control
- Use
revalidate to control ISR
- Seconds for periodic revalidation
false disables revalidation
export const revalidate = 3600;
export default function Page() {
return <div>Content</div>;
}
🌐 Route Segment & API Directives
API & Middleware
- API routes can have
dynamic and revalidate
- Middleware can use
config.matcher
- Useful for caching and dynamic behavior control
export const dynamic = 'force-dynamic';
export const revalidate = 0;
export async function GET() {
return Response.json({ users: [] });
}
📝 Metadata & Viewport
Metadata & Viewport Settings
metadata can be static or dynamic
generateMetadata fetches runtime data
viewport defines device scaling
export const metadata = { title: 'My Page', description: 'Page description' };
export const viewport = { width: 'device-width', initialScale: 1, maximumScale: 1 };
⚙️ Performance & Optimization
Package & Import Optimization
- Use
optimizePackageImports for large libraries
- Modularize imports to reduce bundle size
- Preload critical images with Next/Image
export const optimizePackageImports = ['lodash', 'react-icons'];
export const modularizeImports = { 'react-icons': { transform: 'react-icons/{{member}}' } };
Optimized Image Component
import Image from 'next/image';
export default function OptimizedImage({ src, alt }) {
return <Image src={src} alt={alt} width={500} height={300} priority placeholder="blur" blurDataURL="data:image/jpeg;base64,..." />;
}
🔁 Conditional Directives
Environment-Based Rendering
- Environment-based dynamic/static rendering
- Adjust
revalidate depending on dev or prod
- Useful for feature flags
export const dynamic = process.env.NODE_ENV === 'production' ? 'force-static' : 'force-dynamic';
export const revalidate = process.env.NODE_ENV === 'development' ? 0 : 3600;
⚠️ Error Handling Directives
Global Error Component
- Use
app/error.js for global errors
- Provide retry/reset UI
- Keep boundaries lightweight
'use client';
export default function Error({ error, reset }) {
return <div><h2>Something went wrong!</h2><button onClick={reset}>Try again</button></div>;
}
Not Found Page
app/not-found.js for missing pages
- Provides friendly 404 message
- Keeps routing predictable
export default function NotFound() {
return <div><h2>Page not found</h2><p>Could not find requested resource</p></div>;
}
🧭 Best Practices
Directive Placement & Defaults
- Place directives at the top of the file
- Static rendering by default, dynamic only when needed
- Match
fetchCache to data volatility
'use client';
export const dynamic = 'force-dynamic';
export const revalidate = 3600;
export default function Component() { return <div>Content</div>; }