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.

Niveau : intermédiaireDurée : ~1 hHTML · Bootstrap · JavaScript · APICode source gratuit
Moteur de recherche en JavaScript affichant des images Unsplash dans l'onglet Images
Le résultat : une recherche « Chien » dans l’onglet Images

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.

📖 Recherche WikipédiaLes articles correspondant à ta recherche, avec titre et extrait.
🖼️ Recherche d’imagesDes photos libres de droits récupérées sur Unsplash.
🗂️ OngletsBascule entre « Tous » et « Images » comme sur Google.
🚫 Aucun résultatUn message clair quand la recherche ne donne rien.

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
💡
Nouveau en JavaScript ?

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 :

moteur-recherche/ ├── navigateur.html # interface : formulaire, onglets, résultats └── nav.js # logique : appels aux API et affichage

É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.js
🔑
Ta clé Unsplash

Remplace 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

searchWikipedia()Appelle l’API de Wikipédia avec fetch() et attend la réponse avec await.
displayWikipediaResults()Crée un bloc par article trouvé, avec son titre et son extrait.
searchImages()Interroge l’API Unsplash avec ta clé et affiche les photos.
OngletsDeux écouteurs click affichent « Tous » ou « Images ».
FormulaireL’événement submit lance la recherche sans recharger la page.
displayNoResultsMessage()Affiche un message quand aucun résultat n’est trouvé.
ℹ️
Wikipédia en français

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.html dans 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

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 !

Comments

No comments yet. Why don’t you start the discussion?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *