Dans ce tutoriel, tu vas créer un moteur de recherche en JavaScript qui cherche des articles sur Wikipédia et des photos sur Unsplash, avec une interface en HTML et Bootstrap et des onglets « Tous » et « Images ». Un projet concret pour apprendre à utiliser des API avec fetch(), async/await et la manipulation du DOM.

Ce que tu vas construire : un moteur de recherche en JavaScript
Ce projet te fait passer un cap : au lieu de travailler uniquement avec tes propres données, ton moteur de recherche en JavaScript va interroger des services externes en temps réel grâce à leurs API.
Prérequis
- Les bases de HTML et de JavaScript
- Des notions de fetch() et de
async/await(on les explique au passage) - Un éditeur de code, un navigateur récent et une connexion Internet
- Une clé d’accès Unsplash gratuite, à créer sur unsplash.com/developers
Commence par un projet sans API, comme l’application de gestion de tâches en JavaScript, puis reviens ici.
Étape 1 : préparer le projet
Crée un dossier avec deux fichiers :
Étape 2 : construire l’interface (navigateur.html)
L’interface utilise Bootstrap pour un rendu propre sans effort : un champ de recherche, un bouton, deux onglets et les zones qui recevront les résultats.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Recherche Texte et Images</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
padding-top: 50px;
background-color: rgb(245, 251, 252);
color: black;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1;
}
.search-results, #search-result {
margin-top: 20px;
}
#search-result {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20px;
}
#search-result img {
width: 100%;
height: auto;
object-fit: cover;
border-radius: 5px;
}
#show-more-btn {
display: none;
margin-top: 20px;
}
.nav-tabs {
margin-bottom: 20px;
}
footer {
background-color: #f8f9fa;
padding: 20px 0;
text-align: center;
border-top: 1px solid #ddd;
}
footer a {
color: #007bff;
text-decoration: none;
margin: 0 10px;
}
footer a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="content">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<h3>Application de recherche de Texte Wikipédia et d'Images</h3>
<div id="image-container" class="mb-5 d-flex justify-content-center">
<img id="image" src="logo1.png" alt="Logo" class="img-fluid">
</div>
<!-- Formulaire de recherche -->
<form id="searchForm">
<div class="input-group mb-3">
<input type="text" class="form-control" id="searchQuery" placeholder="Entrez votre recherche">
<div class="input-group-append">
<button class="btn btn-primary" type="submit">Rechercher</button>
</div>
</div>
</form>
<!-- Onglets pour les résultats -->
<ul class="nav nav-tabs" id="resultTabs">
<li class="nav-item">
<a class="nav-link active" id="all-tab" href="#">Tous</a>
</li>
<li class="nav-item">
<a class="nav-link" id="images-tab" href="#">Images</a>
</li>
</ul>
<!-- Résultats -->
<div id="results" class="search-results">
<!-- Les résultats textuels apparaîtront ici -->
</div>
<div id="search-result" style="display: none;">
<!-- Les résultats d'images apparaîtront ici -->
</div>
<button id="show-more-btn" class="btn btn-secondary" style="display: none;">Voir plus</button>
</div>
</div>
</div>
</div>
<!-- Footer -->
<footer>
<p>© 2024 LM-Code. Tous droits réservés.</p>
<p>
<a href="https://lm-code.be">Site Web</a> |
<a href="https://www.youtube.com/@lm-codeOfficiel">Chaine Youtube</a> |
<a href="https://lm-code.be">LM-Code</a>
</p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="nav.js"></script>
</body>
</html>navigateur.htmlÉtape 3 : ajouter la logique JavaScript (nav.js)
C’est le cœur de ton moteur de recherche en JavaScript. Ce fichier interroge les deux API, affiche les résultats et gère les onglets :
const allTab = document.getElementById("all-tab");
const imagesTab = document.getElementById("images-tab");
const resultsContainer = document.getElementById("results");
const imagesContainer = document.getElementById("search-result");
const showMoreBtn = document.getElementById("show-more-btn");
// Gestion des clics sur les onglets
allTab.addEventListener("click", function (e) {
e.preventDefault();
allTab.classList.add("active");
imagesTab.classList.remove("active");
resultsContainer.style.display = "block";
imagesContainer.style.display = "none";
showMoreBtn.style.display = "none";
});
imagesTab.addEventListener("click", function (e) {
e.preventDefault();
allTab.classList.remove("active");
imagesTab.classList.add("active");
resultsContainer.style.display = "none";
imagesContainer.style.display = "grid";
if (imagesContainer.children.length > 0) {
showMoreBtn.style.display = "block";
}
});
// Rechercher sur Wikipedia
async function searchWikipedia(query) {
const url = `https://en.wikipedia.org/w/api.php?origin=*&action=query&list=search&srsearch=${encodeURIComponent(query)}&utf8=&format=json`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.query.search.length > 0) {
displayWikipediaResults(data.query.search, resultsContainer);
} else {
displayNoResultsMessage(resultsContainer, "Aucun résultat trouvé sur Wikipedia.");
}
} catch (error) {
displayNoResultsMessage(resultsContainer, "Erreur lors de la recherche sur Wikipedia.");
}
}
// Afficher les résultats Wikipedia
function displayWikipediaResults(results, container) {
container.innerHTML = ""; // Nettoyer les résultats précédents
let groupTitle = document.createElement("h3");
groupTitle.textContent = "Résultats Wikipedia";
container.appendChild(groupTitle);
results.forEach(result => {
const item = document.createElement("div");
item.className = "result-item p-3 mb-2 bg-light border";
item.innerHTML = `
<h4><a href="https://en.wikipedia.org/?curid=${result.pageid}" target="_blank">${result.title}</a></h4>
<p>${result.snippet}...</p>`;
container.appendChild(item);
});
}
// Gérer les images Unsplash
const accessKey = "VOTRE_CLE_UNSPLASH";
let page = 1;
async function searchImages(query) {
const url = `https://api.unsplash.com/search/photos?page=${page}&query=${query}&client_id=${accessKey}&per_page=12`;
try {
const response = await fetch(url);
const data = await response.json();
if (page === 1) {
imagesContainer.innerHTML = "";
}
data.results.forEach(result => {
const img = document.createElement("img");
img.src = result.urls.small;
const link = document.createElement("a");
link.href = result.links.html;
link.target = "_blank";
link.appendChild(img);
imagesContainer.appendChild(link);
});
if (data.results.length > 0) {
showMoreBtn.style.display = "block";
} else if (page === 1) {
displayNoResultsMessage(imagesContainer, "Aucune image trouvée.");
}
} catch (error) {
displayNoResultsMessage(imagesContainer, "Erreur lors de la recherche d'images.");
}
}
// Lancer la recherche
document.getElementById("searchForm").addEventListener("submit", function (e) {
e.preventDefault();
const query = document.getElementById("searchQuery").value.trim();
if (query) {
resultsContainer.innerHTML = "";
imagesContainer.innerHTML = "";
searchWikipedia(query);
searchImages(query);
}
});
// Bouton "Voir plus"
showMoreBtn.addEventListener("click", function () {
page++;
searchImages(document.getElementById("searchQuery").value);
});
// Gérer les erreurs
function displayNoResultsMessage(container, message) {
container.innerHTML = `<div class="alert alert-danger">${message}</div>`;
}nav.jsRemplace la valeur de accessKey par ta propre clé d’accès Unsplash. Ne publie jamais une vraie clé dans un dépôt public : pour un projet en ligne, fais passer les appels par un petit serveur qui garde la clé secrète.
Comment fonctionne ce code
fetch() et attend la réponse avec await.click affichent « Tous » ou « Images ».submit lance la recherche sans recharger la page.Le code interroge la version anglaise (en.wikipedia.org). Pour des résultats en français, remplace simplement en par fr dans l’adresse de l’API.
Étape 4 : tester ton moteur de recherche
- Ouvre
navigateur.htmldans ton navigateur - Tape un mot-clé (par exemple « chien ») et lance la recherche
- Bascule entre les onglets « Tous » et « Images »
- Si les images ne s’affichent pas, vérifie ta clé Unsplash et la console du navigateur (F12)
Aller plus loin
- Ajouter une pagination ou un bouton « Charger plus »
- Ajouter un thème sombre avec un bouton de bascule
- Afficher un indicateur de chargement pendant les requêtes
- Garder ta clé secrète en créant une petite API avec Flask, comme dans le projet application de diagnostic PC avec Flask
- Pratiquer encore le JavaScript avec le générateur de citations et proverbes ou la Quiz App
FAQ : questions fréquentes
Faut-il payer pour utiliser les API ?
Non. L’API de Wikipédia est libre d’accès, et Unsplash propose une clé gratuite pour les projets de démonstration, avec un nombre limité de requêtes par heure.
Pourquoi les images ne s’affichent pas ?
Le plus souvent, la clé Unsplash est absente ou invalide. Ouvre la console du navigateur (F12) : une erreur 401 confirme un problème de clé.
Est-ce que je peux mettre ma clé directement dans le JavaScript ?
Pour tester en local, oui. Mais tout code JavaScript est visible par les visiteurs : pour un site en ligne, la clé doit rester côté serveur.
Pourquoi utiliser async/await ?
Les appels aux API prennent du temps. async/await permet d’attendre la réponse sans bloquer la page, avec un code plus lisible que les promesses enchaînées.
Bravo, ton moteur de recherche en JavaScript est opérationnel ! Tu sais maintenant interroger des API et afficher leurs résultats. Partage tes améliorations ou tes questions en commentaire !

