Next.js Features
Server Component (Default)
async function Page() {
const data = await fetch('https://api.example.com/data');
const json = await data.json();
return <div>{json.title}</div>;
}
Client Component
'use client'
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Dynamic Route
// app/blog/[slug]/page.tsx
export default function Post({ params }: { params: { slug: string } }) {
return <h1>Post: {params.slug}</h1>;
}
// app/actions.ts
'use server'
export async function createTodo(formData: FormData) {
const title = formData.get('title');
// Mutate data (e.g., db.insert)
}
// app/page.tsx
import { createTodo } from './actions'
export default function Page() {
return (
<form action={createTodo}>
<input name="title" />
<button type="submit">Add Todo</button>
</form>
)
}
Middleware (Route Guard)
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/request';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
export const config = {
matcher: ['/dashboard/:path*', '/profile/:path*'],
};
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Home Page',
description: 'Welcome to my site',
};
import type { Metadata } from 'next';
export async function generateMetadata({ params }): Promise<Metadata> {
const product = await fetchProduct(params.id);
return { title: product.name };
}
Image Optimization
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero Image"
width={800}
height={600}
priority
/>
Revalidate Data
fetch('https://...', { next: { revalidate: 3600 } }); // 1 hour
Pathname & Params (Client)
'use client'
import { usePathname, useSearchParams } from 'next/navigation';
function ClientInfo() {
const pathname = usePathname();
const searchParams = useSearchParams();
}