Building A Book Search Engine with PromptJoy and Next.js

In this tutorial, we are going to build a book search engine using Next.js, an open-source development framework built on top of Node.js. We'll be leveraging two APIs provided by PromptJoy: the Book Search API and the Book Summary API. These APIs will allow our search engine to retrieve book results based on user queries and provide a detailed summary for each book.

One of the exciting features of PromptJoy is that you can create your own APIs to customize the functionality of your search engine. For instance, you could create APIs for searching and summarizing different types of content like movies, songs, recipes, etc.

PromptJoy APIs

  1. Book Search API: This API (https://preview.promptjoy.com/apis/mVMCpq) acts as a book search engine. When provided with a query, it returns 3 book results that match the query. Each result includes the title and author of a book.

    • Endpoint: https://api.promptjoy.com/api/mVMCpq

    • Method: POST

    • API Key: You need to include your unique API key in the request header to authenticate your requests. We'll discuss how to set this up later in the tutorial.

  2. Book Summary API: This API (https://preview.promptjoy.com/apis/jJbC2p) acts as a book database. When given the title and author of a book, it returns a detailed summary of the book.

    • Endpoint: https://api.promptjoy.com/api/jJbC2p

    • Method: POST

    • API Key: You need to include your unique API key in the request header to authenticate your requests.

Project Setup

First, let's create a new Next.js application. We are using Next.js version 12 in this tutorial. You can do this by running the following command in your terminal:

npx create-next-app@12 book-search-engine

Then, navigate into your new project directory:

cd book-search-engine

Next, install the necessary dependencies. We will be using axios for making HTTP requests and react-spinners for displaying a loading spinner:

npm install axios react-spinners @emotion/react @emotion/styled

Creating the Search Engine

Now, let's create our book search engine. We'll need to create a form for users to enter their search queries, a component to display the search results, and a function to handle the search.

In your pages directory, create a new file called index.js and copy the following code:

import React, { useState } from 'react';
import axios from 'axios';
import { css } from "@emotion/react";
import { BeatLoader } from "react-spinners";

const override = css`
  display: block;
  margin: 0 auto;
  border-color: red;
`;

function Book({book, onClick}) {
  return (
    <div className="p-4 bg-white rounded-lg shadow-md mt-5">
      <h2 className="text-blue-500 cursor-pointer" onClick={() => onClick(book)}>{book.title}</h2>
      <h3 className="text-gray-700">{book.author}</h3>
    </div>
  )
}

export default function Home() {
  const [books, setBooks] = useState([]);
  const [query, setQuery] = useState('');
  const [loading, setLoading] = useState(false);
  const [loadingSummary, setLoadingSummary] = useState(false);

  const searchBooks = async (event) => {
    event.preventDefault();
    setLoading(true);
    const response = await axios.post(
      'https://api.promptjoy.com/api/mVMCpq',
      { query },
      {
        headers: {
         'Content-Type': 'application/json',
          'x-api-key': process.env.PROMPTJOY_API_KEY,
        },
      }
    );
    setBooks(response.data);
    setLoading(false);
  };

  const fetchSummary = async (book) => {
    setLoadingSummary(true);
    const response = await axios.post(
      'https://api.promptjoy.com/api/jJbC2p',
      { title: book.title, author: book.author },
      {
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': process.env.PROMPTJOY_API_KEY,
        },
      }
    );
    alert(response.data.summary);
    setLoadingSummary(false);
  };

  return (
    <div className="container mx-auto px-4 py-5">
      <h1 className="text-3xl font-semibold text-center mb-5">Book Search Engine</h1>
      <form className="w-full max-w-md mx-auto" onSubmit={searchBooks}>
        <input
          type="text"
          className="w-full shadow border rounded py-2 px-3 mb-5 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
          id="query"
          placeholder="Search for books..."
          value={query}
          onChange={e => setQuery(e.target.value)}
        />
        <button
          className="w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
          type="submit"
        >
          Search
        </button>
        <div className="mt-2">
          {loading && <BeatLoader color={"#123abc"} loading={loading} css={override} size={15} />}
          {loadingSummary && <BeatLoader color={"#123abc"} loading={loadingSummary} css={override} size={15} />}
        </div>
      </form>
      <div className="mt-5">
        {books.map((book, index) => (
          <Book key={index} book={book} onClick={fetchSummary} />
        ))}
      </div>
    </div>
  );
}

In this code, we have a Home component which acts as the main page of our application. Inside this component, we have a form that takes in a search query from the user. When the form is submitted, it triggers the searchBooks function which makes a request to the Book Search API with the provided query, retrieves the results, and sets them in the books state.

The books state is then mapped to our Book component which displays each book title and author. The title of the book is clickable, and when clicked, it triggers the fetchSummary function. This function makes a request to the Book Summary API with the book title and author, retrieves the book summary, and displays it in an alert.

Finally, we have a loading spinner that displays while the requests to the APIs are being processed. The spinner is centered under the search button and will disappear once the requests are complete.

Deploying to Vercel

Deploying your Next.js application to Vercel is straightforward. First, you need to push your application to a GitHub repository. Then, go to Vercel, sign up for a new account or log in to your existing one, and import your GitHub repository. Vercel will automatically detect that your application is a Next.js app and will provide sensible default configurations.

Lastly, you'll need to set your PromptJoy API key as an environment variable in Vercel. You can do this by going to your project settings, thento the "Environment Variables" section, and adding a new variable with the name PROMPTJOY_API_KEY and the value being your actual API key.

Once that's done, click "Deploy", and Vercel will automatically build and deploy your application.

And there you have it! You've built a book search engine using Next.js and PromptJoy. This is just the beginning, though. The great thing about PromptJoy is that you can build your own APIs to create a search engine that's perfectly tailored to your needs. Whether you want to search for books, movies, music, or anything else, you can create an API for it and integrate it into your search engine.

Remember to secure your API keys and to regularly update your application to ensure its security and performance. Happy coding!

Last updated