How to build Quiz generator with Next js and Gemin 2.5 in 2 hours

quizcreator proquizcreator pro
3 min read

Building a Quiz Generator with Next.js and Gemini 2.5

Creating interactive quiz applications is a great way to engage users, and with modern tools like Next.js and Gemini 2.5, it’s easier than ever. In this article, I’ll share how I built a quiz generator using these technologies, inspired by resources like Quiz Creator Pro.

Project Setup

First, I set up a Next.js project with Tailwind CSS for styling:

npx create-next-app@latest quiz-generator --tailwind

I chose JavaScript and the App Router for simplicity. After setup, I ran the development server to ensure everything worked:

cd quiz-generator && npm run dev

Integrating Gemini 2.5

To generate dynamic quiz questions, I used the Gemini 2.5 API. I installed the @google/generative-ai package:

npm install @google/generative-ai

In pages/api/generate-quiz.js, I created an API route to handle quiz generation:

import { NextResponse } from "next/server";
import { GoogleGenerativeAI } from "@google/generative-ai";

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);

export async function POST(req) {
  try {
    const { topic, numQuestions, difficulty } = await req.json();
    const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" });
    const prompt = `Generate a quiz with ${numQuestions} multiple-choice questions on ${topic} at ${difficulty} difficulty. Return in JSON format with keys: question, options, correct.`;
    const result = await model.generateContent(prompt);
    let quiz = result.response.text().replace(/```json|```/g, "").trim();
    quiz = JSON.parse(quiz);
    return NextResponse.json(quiz);
  } catch (error) {
    return NextResponse.json({ message: "Error generating quiz" }, { status: 500 });
  }
}

I stored the Gemini API key in a .env.local file for security.

Building the Frontend

In app/page.jsx, I created a simple UI with a form to input quiz parameters and display questions:

"use client";
import { useState } from "react";

export default function Home() {
  const [topic, setTopic] = useState("");
  const [numQuestions, setNumQuestions] = useState(5);
  const [difficulty, setDifficulty] = useState("medium");
  const [quiz, setQuiz] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const res = await fetch("/api/generate-quiz", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ topic, numQuestions, difficulty }),
    });
    const data = await res.json();
    setQuiz(data);
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Quiz Generator</h1>
      <form onSubmit={handleSubmit} className="mb-4">
        <input
          type="text"
          placeholder="Topic"
          value={topic}
          onChange={(e) => setTopic(e.target.value)}
          className="border p-2 mr-2"
        />
        <input
          type="number"
          placeholder="Number of Questions"
          value={numQuestions}
          onChange={(e) => setNumQuestions(e.target.value)}
          className="border p-2 mr-2"
        />
        <select
          value={difficulty}
          onChange={(e) => setDifficulty(e.target.value)}
          className="border p-2 mr-2"
        >
          <option value="easy">Easy</option>
          <option value="medium">Medium</option>
          <option value="hard">Hard</option>
        </select>
        <button type="submit" className="bg-blue-500 text-white p-2 rounded">
          Generate Quiz
        </button>
      </form>
      {quiz && (
        <div>
          {quiz.map((q, index) => (
            <div key={index} className="mb-4">
              <h2 className="text-lg font-semibold">{q.question}</h2>
              {q.options.map((option, i) => (
                <p key={i}>{option}</p>
              ))}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

This component lets users input a topic, number of questions, and difficulty level, then displays the generated quiz.

Styling with Tailwind CSS

Tailwind CSS made styling straightforward. I used utility classes to create a clean, responsive UI. For example, container mx-auto p-4 centers the content, and bg-blue-500 text-white p-2 rounded styles the button.

Challenges and Solutions

One challenge was ensuring the Gemini API returned valid JSON. I used replace(/```json|```/g, "").trim() to clean the response. Another was handling API errors gracefully, which I managed with try-catch blocks.

Conclusion

Using Next.js and Gemini 2.5, I built a quiz generator that creates dynamic, engaging quizzes. This project showcases the power of AI in educational tools. For more inspiration, check out Quiz Creator Pro. Try building your own quiz app and share your experience!

0
Subscribe to my newsletter

Read articles from quizcreator pro directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

quizcreator pro
quizcreator pro