Standalone quizz game package. It can run by itself or be registered inside PlayRoom core.
- 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
npm install @play-room/quizz- 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.
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")!);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.
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
});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
});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.
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()
});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()
});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
}
});