94 cards across 6 sections
page.tsx
layout.tsx
loading.tsx
notFound()
(marketing)
'use client'
useState
useEffect
children
server-only
<form action={fn}>
<form>
Promise.all
cacheComponents
dynamicIO
useCache
ppr
<Suspense>
revalidate
use cache
[slug]
[...slug]
GET
POST
app/api/*/route.ts
NextResponse.json()
@
@modal
(.)
redirect()
metadata
sitemap.xml
robots.txt
ImageResponse
alternates.canonical
images.remotePatterns
next dev
next build
middleware.ts
'use cache'
async function getData() { 'use cache'; const res = await fetch(url); return res.json();}
const [user, posts] = await Promise.all([ getUser(id), getPosts(id),]);
const [state, action, pending] = useActionState(createPost, null);
<Suspense fallback={<Skeleton />}> <Comments postId={id} /></Suspense>
export async function generateStaticParams() { const posts = await getPosts(); return posts.map((p) => ({ slug: p.slug }));}
fetch(url, { next: { tags: ['posts'] } });// after a mutation:revalidateTag('posts');
<Image src={photo} alt="" width={800} height={400} />
import 'server-only';export function getSecret() { return process.env.API_SECRET;}
export const config = { matcher: ['/dashboard/:path*'],};
async function submit() { await save(); redirect('/success'); // outside try/catch}
const Chart = dynamic(() => import('./Chart'), { ssr: false,});
export async function GET(req: NextRequest) { const data = await getData(); return NextResponse.json(data);}
app/dashboard/loading.tsxapp/dashboard/page.tsx
export const metadata = { title: { template: '%s | Acme', default: 'Acme' },};
function SubmitButton() { const { pending } = useFormStatus(); return <button disabled={pending}>Save</button>;}
'use server'
proxy