Create a Quiz App with Next JS (original) (raw)

Last Updated : 10 Oct, 2025

Let’s build an engaging Quiz App using Next.js! Users can answer multiple-choice questions, move through each round smoothly, and check their quiz results once they’re done.

**Output Preview: Let us have a look at how the final output will look like
Screenshot-(450)

Approach to Create Quiz App with Next JS:

Steps to create the Quiz Application:

**Step 1: Create a application of NextJS using the following command.

npx create-next-app@latest quiz-app

**Step 2: Navigate to project directory

cd quiz-app

**Step 3: Install the necessary package in your project using the following command.

npm install bootstrap

Project Structure:

Screenshot-(452)

The updated dependencies in **package.json file will look like:

"dependencies": { "bootstrap": "^5.3.3", "next": "14.1.0", "react": "^18", "react-dom": "^18" }

**Example: Below are the components which describes the basic implementation of the Quiz App.

JavaScript `

// page.js 'use client' import { useState } from "react"; import Quiz from "../Components/Quiz";

export default function Home() { const [quizStarted, setQuizStarted] = useState(false); const [name, setName] = useState('');

return (
    <div className="container mt-5 ml-5">
        <div className="text-center">

            <h1 className='text-success mtb-1 '>
                GeekForGeeks
            </h1>
            <h3 className='mb-4'>Quiz App</h3>
        </div>

        {quizStarted ? (
            <Quiz name={name} />
        ) : (
            <>
                <div className="mb-3">
                    <label htmlFor="nameInput"
                        className="form-label">
                        Enter Your Name:
                    </label>
                    <input
                        type="text"
                        className="form-control"
                        id="nameInput"
                        value={name}
                        onChange={(e) =>
                            setName(e.target.value)}
                    />
                </div>
                <button
                    onClick={() => setQuizStarted(true)}
                    className="btn btn-primary"
                    // Disable button if name is empty or whitespace
                    disabled={!name.trim()}
                >
                    Start Quiz
                </button>
            </>
        )}
    </div>
);

}

` JavaScript ``

// QuestionSet.js export const quiz = { questions: [ { id: 1, question: 'What does API stand for?', answers: ['Application Programming Interface', 'Advanced Programming Interface', 'Application Program Interface', 'Automated Programming Interface'], correctAnswer: 'Application Programming Interface', },

    {
        id: 3,
        question: `Which programming language is often 
        used for building web servers?`,
        answers: ['Java', 'Python', 'JavaScript', 'C#'],
        correctAnswer: 'JavaScript',
    },
    {
        id: 4,
        question: 'What is the purpose of SQL?',
        answers: ['Styling web pages', 'Querying databases',
            'Creating animations', 'Developing mobile apps'],
        correctAnswer: 'Querying databases',
    },
    {
        id: 5,
        question: 'What does MVC stand for in web development?',
        answers: ['Model View Controller', 'Model Visual Controller',
            'Model View Component', 'Model Visual Component'],
        correctAnswer: 'Model View Controller',
    },
],

};

`` JavaScript `

// Quiz.js import React, { useState } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; import { quiz } from '../Data/QuestionSet.js'; import ScoreCard from './ScoreCard.js';

const Quiz = ({ name }) => { const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [selectedAnswer, setSelectedAnswer] = useState(''); const [answerChecked, setAnswerChecked] = useState(false); const [selectedAnswerIndex, setSelectedAnswerIndex] = useState(null); const [showResults, setShowResults] = useState(false); const [quizResult, setQuizResult] = useState({ score: 0, correctAnswers: 0, wrongAnswers: 0, });

const { questions } = quiz;
const { question, answers, correctAnswer } = 
                                            questions[currentQuestionIndex];

const onAnswerSelected = (answer, idx) => {
    setSelectedAnswerIndex(idx);
    setSelectedAnswer(answer);
    setAnswerChecked(true);
};

const handleNextQuestion = () => {
    if (selectedAnswer === correctAnswer) {
        setQuizResult((prev) => ({
            ...prev,
            score: prev.score + 5,
            correctAnswers: prev.correctAnswers + 1,
        }));
    } else {
        setQuizResult((prev) => ({
            ...prev,
            wrongAnswers: prev.wrongAnswers + 1,
        }));
    }
    if (currentQuestionIndex !== questions.length - 1) {
        setCurrentQuestionIndex((prev) => prev + 1);
    } else {
        setShowResults(true);
    }
    setSelectedAnswer('');
    setSelectedAnswerIndex(null);
    setAnswerChecked(false);
};

return (
    <div className='container mt-5'>

        <div>
            {!showResults ? (
                <div className='card p-4'>
                    <h4>{question}</h4>
                    <ul className='list-group'>
                        {answers.map((answer, idx) => (
                            <li
                                key={idx}
                                onClick={() => onAnswerSelected(answer,idx)}
                                className={
                                    'list-group-item ' +
                                    (selectedAnswerIndex === 
                                            idx ? 'active' : '') +
                                    ' cursor-pointer'
                                }
                            >
                                {answer}
                            </li>
                        ))}
                    </ul>
                    <div className='d-flex justify-content-between mt-3'>
                        <b>Question
                            {currentQuestionIndex + 1}/{questions.length}
                        </b>
                        <button
                            onClick={handleNextQuestion}
                            className='btn btn-primary'
                            disabled={!answerChecked}
                        >
                            {currentQuestionIndex === questions.length - 1 ?
                                'Submit' : 'Next Question'}
                        </button>
                    </div>
                </div>
            ) : (
                <ScoreCard
                    quizResult={quizResult}
                    questions={questions}
                    name={name}
                />
            )}
        </div>
    </div>
);

};

export default Quiz;

JavaScript

// ScoreCard.js import React from 'react';

const ScoreCard = ({ quizResult, questions, name }) => { const passPercentage = 60;

const percentage = (quizResult.score / (questions.length * 5)) * 100;
const status = percentage >= passPercentage ? 'Pass' : 'Fail';

return (
    <>
        <div className='card p-4'>
            <h3>Hello, {name}. Here is your Result Analysis</h3>
            <table className='table'>
                <tbody>
                    <tr>
                        <td>Total Questions:</td>
                        <td>{questions.length}</td>
                    </tr>
                    <tr>
                        <td>Total Score:</td>
                        <td>{quizResult.score}</td>
                    </tr>
                    <tr>
                        <td>Correct Answers:</td>
                        <td>{quizResult.correctAnswers}</td>
                    </tr>
                    <tr>
                        <td>Wrong Answers:</td>
                        <td>{quizResult.wrongAnswers}</td>
                    </tr>
                    <tr>
                        <td>Percentage:</td>
                        <td>{percentage}%</td>
                    </tr>
                    <tr>
                        <td>Status:</td>
                        <td>{status}</td>
                    </tr>
                </tbody>
            </table>
            <button
                onClick={() => window.location.reload()}
                className='btn btn-primary mt-3'
            >
                Restart
            </button>
        </div>
    </>
);

};

export default ScoreCard;

`

**Start your application using the following command.

npm run dev

**Output: Naviage to the URL **http://localhost:3000.