Quiz JSON schema

Every quiz is one JSON file at content/quizzes/<slug>.json. The filename must match the slug field. Here is a complete example:

{
	"slug": "which-element-are-you",
	"title": "Which Element Are You?",
	"description": "Discover your dominant element.",
	"enabled": true,
	"questions": [
		{
			"id": "q1",
			"text": "Pick a place to relax.",
			"options": [
				{ "id": "q1-a", "text": "A windy cliff", "scores": { "air": 2, "fire": 1 } },
				{ "id": "q1-b", "text": "A warm hearth", "scores": { "fire": 3 } }
			]
		}
	],
	"results": [
		{ "id": "air", "title": "Air", "description": "Free-spirited and curious." },
		{ "id": "fire", "title": "Fire", "description": "Passionate and bold." }
	]
}

Top-level fields

FieldTypeRules
slugstringlowercase kebab-case (a-z, 0-9, hyphens); must equal the filename
titlestringshown on the homepage and quiz page; 1–200 chars
descriptionstringone-paragraph intro; 1–500 chars
enabledbooleanfalse hides the quiz from the public site (admins still see it)
questionsarray1–100 questions; order = play order
resultsarray1–20 results; order = tie-break order

Question fields

FieldTypeRules
idstringunique within the quiz; convention is q1, q2, …
textstringthe question shown to the player
optionsarray2–10 options

Option fields

FieldTypeRules
idstringunique within its question; convention q1-a, q1-b, …
textstringthe answer label
scoresobjectmaps result id → integer points (see below)

scores must only reference result ids that exist in results, and values must be integers. An option may feed multiple results, e.g. { "air": 2, "fire": 1 }.

Result fields

FieldTypeRules
idstringunique; referenced by scores
titlestringheadline of the result card
descriptionstringbody of the result card

Validation

Before a quiz can be enabled it must pass validation:

  1. valid JSON, all required fields present;
  2. slug matches filename and kebab-case;
  3. every question and option id unique;
  4. every option has ≥ 2 sibling options and valid scores;
  5. every scores key references an existing result;
  6. at least one result is reachable (a warning, not an error).

A quiz that fails validation shows Broken in the admin dashboard and displays a friendly “this quiz is broken” page on its public link.