@play-room/quizz
v0.1.2
Published
Smart quizz game with multiple categories and languages, powered by PlayRoom
Readme
@play-room/quizz
Standalone quizz game package. It can run by itself or be registered inside PlayRoom core.
What It Includes
- multi-step start flow
- category and question-language support
- global answers key support
- credits and leaderboard persistence
- built-in light and dark themes
- configurable primary and secondary brand colors
- built-in UI localization with
enandsr - optional external control of UI locale and theme
Install
npm install @play-room/quizzDefault Data Sources
- Questions:
https://raw.githubusercontent.com/Play-Room/data/refs/heads/main/quizz/technology/en.json - Answers:
https://raw.githubusercontent.com/Play-Room/data/refs/heads/main/quizz/answers.json
By default, answers are loaded from the single global answers.json file for all categories and languages.
Standalone Usage
import { createQuizzApp } from "@play-room/quizz";
const app = createQuizzApp({
questionsUrlPattern:
"https://raw.githubusercontent.com/Play-Room/data/refs/heads/main/quizz/{category}/{language}.json",
answersUrl: "https://raw.githubusercontent.com/Play-Room/data/refs/heads/main/quizz/answers.json",
categories: {
technology: "Technology",
science: "Science",
sports: "Sports"
},
languages: {
en: "English",
sr: "Српски"
},
defaultCategory: "technology",
defaultLanguage: "en",
limit: 5,
randomizeQuestions: true,
persistPlayerByClient: true,
themeColors: {
primary: "#0f766e",
secondary: "#14b8a6"
},
locale: "en",
showLocaleSwitcher: true,
theme: "light",
showThemeSwitcher: true
});
await app.mount(document.getElementById("app")!);Theme Colors
Use themeColors.primary and themeColors.secondary to adapt the package to the host dashboard color system.
createQuizzApp({
themeColors: {
primary: "#1d4ed8",
secondary: "#2563eb"
}
});These colors are applied in both light and dark mode.
UI Localization
The package ships with built-in UI locales:
ensr
Use locale for a fixed language:
createQuizzApp({
locale: "sr"
});Show the built-in locale selector in the header:
createQuizzApp({
locale: "en",
showLocaleSwitcher: true
});External Locale Control
Use getLocale and onLocaleChange when the host app owns the locale state.
let currentLocale = "en";
const app = createQuizzApp({
getLocale: () => currentLocale,
onLocaleChange: (nextLocale) => {
currentLocale = nextLocale;
},
showLocaleSwitcher: true
});External Theme Control
Use theme, getTheme, and onThemeChange when the host app owns theme state.
let currentTheme = "dark";
const app = createQuizzApp({
getTheme: () => currentTheme,
onThemeChange: (nextTheme) => {
currentTheme = nextTheme;
},
showThemeSwitcher: true
});Set showThemeSwitcher: false if the dashboard already provides its own theme toggle.
Progress Persistence
By default, credits and leaderboard data are stored in IndexedDB with IndexedDbQuizzProgressService.
Override it if you need custom persistence:
import { createQuizzApp, QuizzProgressService } from "@play-room/quizz";
class CustomProgressService implements QuizzProgressService {
async getCredits(playerName: string) { return 0; }
async addCredits(playerName: string, amount: number) { return amount; }
async addLeaderboardEntry(entry) {}
async getLeaderboard(limit = 20) { return []; }
}
createQuizzApp({
progressService: new CustomProgressService()
});Custom Question and Answer Sources
import { createQuizzApp, QuizzContentService } from "@play-room/quizz";
class CustomQuizzService implements QuizzContentService {
async loadQuestions(options) {
const category = options?.category ?? "technology";
const language = options?.language ?? "en";
const response = await fetch(`/api/quizz/${category}/${language}`);
return response.json();
}
async loadAnswerKey() {
const response = await fetch("/api/quizz/answers");
return response.json();
}
}
createQuizzApp({
contentService: new CustomQuizzService()
});Optional PlayRoom Integration
import { PlayRoom } from "@play-room/core";
import { createQuizzMetadataDefinition } from "@play-room/quizz";
const hub = new PlayRoom();
hub.registerGame({
game: createQuizzMetadataDefinition(),
config: {
questionsUrlPattern: "https://example.com/quizz/{category}/{language}.json",
answersUrl: "https://example.com/quizz/answers.json",
categories: {
technology: "Technology",
science: "Science"
},
languages: {
en: "English",
sr: "Српски"
},
locale: "en",
showLocaleSwitcher: true,
showThemeSwitcher: true
}
});