Génère une clé API, sécurise-la et configure l’appel serveur à TMDB.
Renseigne ton email pour débloquer immédiatement cette formation gratuite.
Dans cette leçon, tu vas apprendre à intégrer l’API de The Movie Database (TMDB) dans une app Next.js 15 full-stack. On va :
fetchMovieDb
.Copie ta clé API dans un fichier .env
à la racine du projet.
1THEMOVIEDB_API_KEY=ton_token_secret
On va centraliser l’appel fetch
pour injecter automatiquement le token.
1'use server';2const API_KEY = process.env.THEMOVIEDB_API_KEY;34export async function fetchMovieDb({ url }: { url: `/${string}` }) {5const res = await fetch(`https://api.themoviedb.org/3${url}`, {6method: 'GET',7headers: {8accept: 'application/json',9Authorization: `Bearer ${API_KEY}`,10},11});12if (!res.ok) {13throw new Error(`TMDB error: ${res.status}`);14}15return res.json();16}
On place cette logique sous "use server"
pour garder ta clé secrète hors du bundle client.
Installe Zod :
1npm install zod
Définis un schéma et une fonction getMovies
:
1import { z } from 'zod';23const MoviesSchema = z.object({4page: z.number(),5results: z.array(6z.object({7id: z.number(),8title: z.string(),9poster_path: z.string(),10release_date: z.string(),11})12),13});1415export async function getMovies() {16const raw = await fetchMovieDb({ url: '/movie/popular' });17const data = MoviesSchema.parse(raw);18return data.results;19}
Dans app/page.tsx
, transforme le composant en async
et appelle getMovies()
:
1import { getMovies } from './server/movies';23export default async function Home() {4const movies = await getMovies(); // Récupère un tableau typé Movie[]5return (6<main className="p-8">7<h1 className="text-4xl font-bold">Films populaires</h1>8<div className="mt-6 grid grid-cols-2 md:grid-cols-4 gap-4">9{movies.map(movie => (10<div key={movie.id}>{movie.title}</div>11))}12</div>13</main>14);15}
Seules les React Server Components (avec async
) peuvent await une méthode serveur.
Pour chaque film, affiche l’affiche optimisée avec next/image
:
1import Image from 'next/image';23export function MovieCard({4title,5poster_path,6release_date,7}: {8title: string;9poster_path: string;10release_date: string;11}) {12return (13<div className="rounded shadow overflow-hidden">14<div className="relative h-48 w-full">15<Image16src={`https://image.tmdb.org/t/p/w500${poster_path}`}17alt={title}18fill19className="object-cover"20/>21</div>22<div className="p-2">23<h2 className="font-semibold">{title}</h2>24<p className="text-sm text-gray-500">25{new Date(release_date).getFullYear()}26</p>27</div>28</div>29);30}
Modifie le rendu de Home
pour utiliser MovieCard
:
1import { getMovies } from './server/movies';2import { MovieCard } from './components/MovieCard';34export default async function Home() {5const movies = await getMovies();6return (7<main className="p-8">8<h1 className="text-4xl font-bold">Films populaires</h1>9<div className="mt-6 grid grid-cols-2 md:grid-cols-4 gap-4">10{movies.map(movie => (11<MovieCard key={movie.id} {...movie} />12))}13</div>14</main>15);16}
Next.js exige que tu déclares l’hôte externe dans next.config.js
:
1module.exports = {2images: {3remotePatterns: [4{5protocol: 'https',6hostname: 'image.tmdb.org',7},8],9},10};
.env
.fetchMovieDb
sous un module serveur.MovieCard
et next/image
./tv/popular
.?page=2
).[id]
pour afficher les détails d’un film (via /movie/{id}
).