How to Add New Questions to the Vue.js Quiz App in Microsoft's AI for Beginners
Add new questions by editing JSON files in etc/quiz-app/src/assets/translations/<locale>/, importing any new lesson files into index.js, and ensuring the quiz id matches your URL route.
The microsoft/AI-For-Beginners repository includes a Vue.js quiz application that renders interactive assessments for each lesson. This guide explains exactly how to add new questions to existing quizzes or create entirely new quizzes, based on the actual source code structure.
Where Quiz Data Lives
The quiz app stores all content in JSON translation files rather than a database. Each locale has its own subdirectory:
etc/quiz-app/src/assets/translations/
├── en/
│ ├── index.js
│ ├── lesson-1.json
│ ├── lesson-2.json
│ └── ...
└── es/
├── index.js
├── lesson-1.json
└── ...
Each lesson-*.json file contains an array with one object that defines:
- UI strings:
title,complete,errormessages quizzesarray: one or more quiz objects (typically pre-quiz and post-quiz)
As implemented in microsoft/AI-For-Beginners, the Quiz.vue component imports the aggregated translations through src/assets/translations/index.js, which stitches individual lesson files into a single exported quiz object mapped by numeric index.
The Data Structure for Questions
Every question follows a strict schema inside the quiz array of a quiz object:
{
"questionText": "Which of the following is NOT a type of neural network?",
"answerOptions": [
{ "answerText": "Convolutional Neural Network", "isCorrect": false },
{ "answerText": "Recurrent Neural Network", "isCorrect": false },
{ "answerText": "Decision Tree", "isCorrect": true }
]
}
The Quiz.vue component renders questionText and iterates over answerOptions, checking isCorrect to validate answers. No code changes are needed—only JSON edits.
Adding a New Question to an Existing Quiz
Locate the target lesson file (e.g., en/lesson-1.json) and append your question to the appropriate quiz array:
- Open
etc/quiz-app/src/assets/translations/en/lesson-1.json - Find the quiz you want to extend (pre-quiz ID 101 or post-quiz ID 102)
- Add your question object to the end of that quiz's
quizarray
Example addition to Lesson 1's pre-quiz:
{
"id": 101,
"title": "AI Basics: Pre-Quiz",
"quiz": [
{
"questionText": "Existing question 1...",
"answerOptions": [...]
},
{
"questionText": "Your new question here?",
"answerOptions": [
{ "answerText": "Correct answer", "isCorrect": true },
{ "answerText": "Wrong answer 1", "isCorrect": false },
{ "answerText": "Wrong answer 2", "isCorrect": false }
]
}
]
}
Creating an Entirely New Quiz
To add a new lesson with its own pre- and post-quizzes:
Step 1: Create the Lesson JSON File
Create etc/quiz-app/src/assets/translations/en/lesson-25.json:
[
{
"title": "Generative AI",
"complete": "Quiz completed!",
"error": "Error loading quiz",
"quizzes": [
{
"id": 301,
"title": "Generative AI: Pre-Quiz",
"quiz": [...]
},
{
"id": 302,
"title": "Generative AI: Post-Quiz",
"quiz": [
{
"questionText": "GANs consist of which two components?",
"answerOptions": [
{ "answerText": "Generator and Discriminator", "isCorrect": true },
{ "answerText": "Encoder and Decoder", "isCorrect": false },
{ "answerText": "Transformer and Attention", "isCorrect": false }
]
},
{
"questionText": "Diffusion models generate data by:",
"answerOptions": [
{ "answerText": "Gradually adding noise", "isCorrect": false },
{ "answerText": "Iteratively denoising a noisy sample", "isCorrect": true },
{ "answerText": "Training a single auto-encoder", "isCorrect": false }
]
},
{
"questionText": "Which metric is commonly used to evaluate image quality?",
"answerOptions": [
{ "answerText": "BLEU", "isCorrect": false },
{ "answerText": "FID", "isCorrect": true },
{ "answerText": "ROUGE", "isCorrect": false }
]
}
]
}
]
}
]
Step 2: Register in the Index File
Import and map your new lesson in etc/quiz-app/src/assets/translations/en/index.js:
import x1 from "./lesson-1.json";
import x2 from "./lesson-2.json";
// ... existing imports ...
import x25 from "./lesson-25.json"; // Add this line
const quiz = {
0: x1[0],
1: x2[0],
// ... existing mappings ...
24: x25[0] // Add this line (index 24 = lesson 25)
};
export default quiz;
Step 3: Verify the Route ID
The router in etc/quiz-app/src/router/index.js defines the dynamic route:
{
path: '/quiz/:id',
name: 'Quiz',
component: Quiz
}
Your quiz id (301, 302, etc.) becomes the URL parameter. Navigate to /quiz/301 to test. The Quiz.vue component extracts this.$route.params.id, matches it against q.quizzes in the loaded lesson data, and renders automatically.
Step 4: Add Translations for Other Locales
Repeat the JSON creation and index registration for any additional languages (e.g., es/lesson-25.json and es/index.js) to maintain full i18n support.
How the Component Renders Your Questions
In etc/quiz-app/src/components/Quiz.vue, the rendering logic:
- Reads
this.$root.$i18n.localeto select the language - Loads
questions[currLocale]from the imported translation data - Matches
this.$route.params.idagainstquiz.idin thequizzesarray - Displays
quiz.quiz[currentQuestion].questionTextand iteratesanswerOptions
No template or logic changes are required when you add new questions—only JSON data updates.
Testing Your Changes
Run the development server and verify:
cd etc/quiz-app
npm run serve
Then test:
- Direct URL navigation:
http://localhost:8080/quiz/301 - Answer selection and scoring
- Quiz completion flow
Key Implementation Files
| File | Purpose |
|---|---|
etc/quiz-app/src/assets/translations/en/lesson-*.json |
Stores quiz questions and answers per lesson |
etc/quiz-app/src/assets/translations/en/index.js |
Aggregates all lessons into the exported quiz object |
etc/quiz-app/src/components/Quiz.vue |
Renders questions, handles user interaction, validates answers |
etc/quiz-app/src/router/index.js |
Defines /quiz/:id dynamic route |
Summary
- JSON-driven architecture: All quiz content lives in
translations/<locale>/lesson-*.jsonfiles—no database or API needed - Two-step workflow: Edit lesson JSON, then import in
index.jsif creating new lessons - URL-based routing: Quiz
idvalues map directly to/quiz/:idroutes without router modifications - Automatic rendering:
Quiz.vuedynamically loads and displays any properly structured JSON data - Full i18n support: Replicate files across locale directories for multi-language quizzes
Frequently Asked Questions
Do I need to restart the dev server after editing JSON files?
No—the Vue CLI development server (npm run serve) hot-reloads JSON changes automatically. Save your file and refresh the browser to see updates immediately.
Can I add more than two quizzes per lesson?
Yes. The quizzes array accepts any number of objects. Each needs a unique id to be reachable via /quiz/<id>. The Quiz.vue template iterates over all entries, so additional quizzes render without code changes.
What happens if two quizzes share the same ID?
The Quiz.vue component uses quiz.id to match against the route parameter. If IDs collide, only the first match in the iteration renders, causing unpredictable behavior. Always verify ID uniqueness across all lesson files.
Why does the index use numeric keys like 24: x25[0] instead of the quiz ID?
The index file maps array position to lesson data for efficient lookup, while individual quiz objects inside quizzes use their own id field for routing. This two-level structure separates lesson organization from quiz navigation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →