Next.js Directives Cheatsheet
'use client'
'use client';
import { useState, useEffect } from 'react';
export default function ClientComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Client-side effect');
}, []);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
'use server'
'use client';
import { useFormState } from 'react-dom';
async function submitForm(prevState, formData) {
'use server';
const name = formData.get('name');
await saveToDatabase(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>
);
}
Dynamic Rendering
export const dynamic = 'force-dynamic';
export default function DynamicPage() {
return <div>Rendered on each request</div>;
}
export const dynamic = 'auto';
export const dynamic = 'error';
Static Rendering
export const dynamic = 'force-static';
export default function StaticPage() {
return <div>Rendered at build time</div>;
}
Fetch Cache Control
export const fetchCache = 'force-cache';
export const fetchCache = 'force-no-store';
export const fetchCache = 'auto';
export default async function Page() {
const data = await fetch('https://api.example.com/data');
return <div>{/* content */}</div>;
}
Revalidation
export const revalidate = 3600;
export const revalidate = false;
export const revalidate = 300;
export default function Page() {
return <div>Content</div>;
}
Route Handlers
export const dynamic = 'force-dynamic';
export const revalidate = 0;
export async function GET() {
return Response.json({ users: [] });
}
export async function POST(request) {
const data = await request.json();
return Response.json({ success: true });
}
Metadata Configuration
export const metadata = {
title: 'My Page',
description: 'Page description'
};
export async function generateMetadata({ params, searchParams }) {
const data = await fetch(`/api/posts/${params.id}`);
const post = await data.json();
return {
title: post.title,
description: post.excerpt
};
}
Viewport Configuration
export const viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1
};
Bundle Optimization
export const optimizePackageImports = ['lodash', 'react-icons'];
export const modularizeImports = {
'react-icons': {
transform: 'react-icons/{{member}}'
}
};
Image Optimization
import Image from 'next/image';
export default function OptimizedImage({ src, alt }) {
return (
<Image
src={src}
alt={alt}
width={500}
height={300}
priority={true} // Preload important images
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
);
}
Environment-Based Configuration
export const dynamic = process.env.NODE_ENV === 'production'
? 'force-static'
: 'force-dynamic';
export const revalidate = process.env.NODE_ENV === 'development'
? 0
: 3600;
Feature Flags
export const dynamic = process.env.ENABLE_DYNAMIC === 'true'
? 'force-dynamic'
: 'force-static';
export default function FeaturePage() {
return <div>Feature content</div>;
}
Error Boundaries
'use client';
export default function Error({ error, reset }) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
);
}
Not Found Pages
export default function NotFound() {
return (
<div>
<h2>Page not found</h2>
<p>Could not find requested resource</p>
</div>
);
}
API Route Configuration
export const dynamic = 'force-dynamic';
export const revalidate = 0;
export async function GET() {
const data = await fetch('https://api.example.com/data', {
cache: 'no-store'
});
return Response.json(await data.json());
}
Middleware Configuration
export const config = {
matcher: [
'/api/:path*',
'/((?!_next/static|_next/image|favicon.ico).*)'
]
};
export function middleware(request) {
}
Directive Placement
'use client';
import React from 'react';
export const dynamic = 'force-dynamic';
export const revalidate = 3600;
export default function Component() {
return <div>Content</div>;
}
import React from 'react';
'use client';
Performance Optimization
export const dynamic = 'force-static';
export const dynamic = 'force-dynamic';
export const revalidate = 3600;
export const fetchCache = 'force-cache';
export const fetchCache = 'force-no-store';
Common Patterns
export default function ServerComponent() {
return (
<div>
<h1>Server rendered</h1>
<ClientButton />
</div>
);
}
'use client';
export default function ClientButton() {
return <button onClick={() => alert('clicked')}>Click me</button>;
}
export const dynamic = process.env.NODE_ENV === 'development'
? 'force-dynamic'
: 'force-static';
export const revalidate = 300;
export const dynamic = 'force-dynamic';