Next.js : Framework React Full-Stack
Créez des applications web modernes avec rendu côté serveur et génération statique
Utilisez Node.js 18.18 ou supérieur. Exécutez les commandes à la racine de votre projet.
Prérequis
node -v # >= 18.18
npm -v
Si Node.js n'est pas installé, consultez la documentation nvm.
Démarrage rapide
# Créer un nouveau projet
npx create-next-app@latest mon-app
cd mon-app
npm run dev
Ouvrir http://localhost:3000
Structure du projet
mon-app/
├── app/
│ ├── layout.tsx # Layout racine
│ ├── page.tsx # Page d'accueil
│ └── about/
│ └── page.tsx # Route /about
├── public/ # Fichiers statiques
├── next.config.js # Configuration
└── package.json
Créer des pages
// app/page.tsx
export default function Home() {
return <h1>Accueil</h1>
}
// app/blog/page.tsx
export default function Blog() {
return <h1>Blog</h1>
}
// app/blog/[slug]/page.tsx
export default function Post({ params }: { params: { slug: string } }) {
return <h1>Article : {params.slug}</h1>
}
Récupération de données
// app/posts/page.tsx
async function getPosts() {
const res = await fetch('https://api.example.com/posts')
return res.json()
}
export default async function Posts() {
const posts = await getPosts()
return (
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
)
}
Composants Client vs Serveur
// app/server-component.tsx (par défaut)
export default function ServerComponent() {
return <div>Rendu côté serveur</div>
}
// app/client-component.tsx
'use client'
import { useState } from 'react'
export default function ClientComponent() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
API Routes
// app/api/hello/route.ts
export async function GET() {
return Response.json({ message: 'Hello' })
}
export async function POST(request: Request) {
const body = await request.json()
return Response.json({ received: body })
}
Layouts
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html lang="fr">
<body>
<header>Mon Site</header>
{children}
<footer>© 2025</footer>
</body>
</html>
)
}
// app/dashboard/layout.tsx
export default function DashboardLayout({ children }) {
return (
<div>
<nav>Menu Dashboard</nav>
{children}
</div>
)
}
Navigation
import Link from 'next/link'
import { useRouter } from 'next/navigation'
export default function Navigation() {
const router = useRouter()
return (
<nav>
<Link href="/">Accueil</Link>
<Link href="/about">À propos</Link>
<button onClick={() => router.push('/dashboard')}>
Dashboard
</button>
</nav>
)
}
Images optimisées
import Image from 'next/image'
export default function Profile() {
return (
<Image
src="/photo.jpg"
alt="Photo de profil"
width={500}
height={500}
priority
/>
)
}
Métadonnées SEO
// app/page.tsx
export const metadata = {
title: 'Accueil',
description: 'Bienvenue sur mon site'
}
// ou dynamique
export async function generateMetadata({ params }) {
const post = await getPost(params.id)
return {
title: post.title,
description: post.excerpt
}
}
Variables d'environnement
# .env.local
DATABASE_URL=postgresql://...
NEXT_PUBLIC_API_URL=https://api.example.com
// Côté serveur uniquement
const dbUrl = process.env.DATABASE_URL
// Côté client (préfixe NEXT_PUBLIC_)
const apiUrl = process.env.NEXT_PUBLIC_API_URL
Scripts package.json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
Build et déploiement
# Build pour production
npm run build
# Démarrer en mode production
npm start
# Analyser le bundle
npm install @next/bundle-analyzer
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withBundleAnalyzer({
reactStrictMode: true,
})
ANALYZE=true npm run build
Configuration courante
// next.config.js
module.exports = {
reactStrictMode: true,
images: {
domains: ['example.com'],
},
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true,
},
]
},
}
Middleware
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: '/dashboard/:path*',
}
Déploiement sur Vercel
npm install -g vercel
vercel login
vercel
Member discussion