A Jeopardy template for your classroom, made with AI and opened from a link

Ask an AI for a Jeopardy board as one HTML page, check the clues, and send yourself the link. Open it on the class screen, click a tile, and play.

A Jeopardy template for the classroom is a grid: categories across the top, point values down each column, and a tile that opens a clue when you click it. You can ask an AI to write that whole grid as one web page.

Open it from a link on the class screen. There is no slide deck to link by hand, and no PowerPoint file, so there are no macros to enable.

Try this one. It is a four-by-four review board for three teams. Click a tile, read the clue, show the answer, then give the points.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Review board</title>
<style>
  * { box-sizing: border-box; }
  body {
    margin: 0; min-height: 100vh; padding: 12px;
    font-family: system-ui, sans-serif; background: #0b1e5b; color: #fff;
  }
  h1 { margin: 0 0 10px; font-size: clamp(18px, 3vw, 26px); text-align: center; letter-spacing: .5px; }
  .board { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .cat {
    display: flex; align-items: center; justify-content: center; text-align: center;
    min-height: 52px; padding: 6px; background: #14308f; border-radius: 6px;
    font-weight: 700; font-size: clamp(12px, 2.4vw, 20px); text-transform: uppercase;
  }
  .tile {
    min-height: 74px; border: 0; border-radius: 6px; cursor: pointer;
    background: #1d4ed8; color: #ffd24a; font-weight: 800; font-size: clamp(20px, 4.5vw, 38px);
  }
  .tile:hover { background: #2a5ee8; }
  .tile:disabled { background: #162a6e; color: #162a6e; cursor: default; }
  .scores { display: flex; gap: 8px; margin-top: 12px; }
  .team { flex: 1; padding: 8px; border-radius: 6px; background: #14308f; text-align: center; }
  .team b { display: block; font-size: clamp(12px, 2.2vw, 16px); font-weight: 600; opacity: .85; }
  .team span { font-size: clamp(20px, 4vw, 32px); font-weight: 800; color: #ffd24a; }
  .reset { margin-top: 10px; background: none; border: 1px solid #5b72c9; color: #cfd8ff; border-radius: 6px; padding: 6px 12px; cursor: pointer; }

  .overlay {
    position: fixed; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 18px; text-align: center; background: #14308f;
  }
  .overlay.open { display: flex; }
  .overlay .tag { font-size: clamp(13px, 2.4vw, 20px); text-transform: uppercase; opacity: .8; }
  .overlay .clue { margin: 0; max-width: 900px; font-size: clamp(22px, 5vw, 46px); font-weight: 700; line-height: 1.25; }
  .overlay .answer { margin: 0; font-size: clamp(22px, 5vw, 42px); font-weight: 800; color: #ffd24a; min-height: 1.3em; }
  .row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
  .row button {
    border: 0; border-radius: 8px; padding: 10px 16px; cursor: pointer;
    background: #ffd24a; color: #0b1e5b; font-weight: 800; font-size: clamp(14px, 2.4vw, 20px);
  }
  .row button.quiet { background: transparent; color: #fff; border: 1px solid #8fa2e8; }
  [hidden] { display: none !important; }
</style>
</head>
<body>
<h1>Review Game</h1>
<div class="board" id="board"></div>
<div class="scores" id="scores"></div>
<button class="reset" id="reset">New game</button>

<div class="overlay" id="overlay">
  <div class="tag" id="tag"></div>
  <p class="clue" id="clue"></p>
  <p class="answer" id="answer"></p>
  <div class="row" id="show-row"><button id="show">Show answer</button></div>
  <div class="row" id="award-row" hidden></div>
</div>

<script>
  // Edit the clues here. Each clue is [points, clue, answer].
  const categories = [
    { name: 'Planets', clues: [
      [100, 'This planet is known as the Red Planet.', 'Mars'],
      [200, 'The largest planet in our solar system.', 'Jupiter'],
      [300, 'This planet is famous for its rings.', 'Saturn'],
      [400, 'The planet closest to the Sun.', 'Mercury'] ] },
    { name: 'Water cycle', clues: [
      [100, 'Liquid water turning into vapor.', 'Evaporation'],
      [200, 'Vapor cooling into tiny droplets that form clouds.', 'Condensation'],
      [300, 'Rain, snow and hail are all forms of this.', 'Precipitation'],
      [400, 'Water flowing over the land back toward the sea.', 'Runoff'] ] },
    { name: 'Fractions', clues: [
      [100, 'One half plus one half equals this whole number.', '1'],
      [200, 'The simplest form of 4/8.', '1/2'],
      [300, '3/4 written as a decimal.', '0.75'],
      [400, 'One third of 12.', '4'] ] },
    { name: 'Words', clues: [
      [100, 'The opposite of ancient.', 'Modern'],
      [200, 'Words with the same meaning are called this.', 'Synonyms'],
      [300, 'The part of speech that names a person, place or thing.', 'Noun'],
      [400, 'A comparison that uses "like" or "as".', 'Simile'] ] },
  ];
  const teams = ['Team A', 'Team B', 'Team C'];

  const $ = (id) => document.getElementById(id);
  let scores, current;

  function el(tag, text) {
    const e = document.createElement(tag);
    if (text !== undefined) e.textContent = text;
    return e;
  }

  function drawScores() {
    $('scores').replaceChildren(...teams.map((name, i) => {
      const box = el('div'); box.className = 'team';
      const label = el('b', name), value = el('span', String(scores[i]));
      box.append(label, value);
      return box;
    }));
  }

  function drawBoard() {
    const cells = categories.map((c) => { const h = el('div', c.name); h.className = 'cat'; return h; });
    for (let row = 0; row < 4; row++) {
      categories.forEach((c, col) => {
        const clue = c.clues[row];
        const tile = el('button', '$' + clue[0]);
        tile.className = 'tile';
        tile.addEventListener('click', () => openClue(tile, c.name, clue));
        cells.push(tile);
      });
    }
    $('board').replaceChildren(...cells);
  }

  function openClue(tile, category, clue) {
    current = { tile, points: clue[0] };
    $('tag').textContent = category + ' for $' + clue[0];
    $('clue').textContent = clue[1];
    $('answer').textContent = '';
    $('award-row').hidden = true;
    $('show-row').hidden = false;
    $('overlay').classList.add('open');
    $('answer').dataset.text = clue[2];
  }

  function closeClue() {
    current.tile.disabled = true;  // used tiles cannot be played again
    $('overlay').classList.remove('open');
  }

  $('show').addEventListener('click', () => {
    $('answer').textContent = $('answer').dataset.text;
    $('show-row').hidden = true;
    const row = $('award-row');
    row.replaceChildren(...teams.map((name, i) => {
      const b = el('button', '+ ' + name);
      b.addEventListener('click', () => { scores[i] += current.points; drawScores(); closeClue(); });
      return b;
    }));
    const none = el('button', 'No one'); none.className = 'quiet';
    none.addEventListener('click', closeClue);
    row.append(none);
    row.hidden = false;
  });

  function newGame() { scores = teams.map(() => 0); drawScores(); drawBoard(); }
  $('reset').addEventListener('click', newGame);
  newGame();
</script>
</body>
</html>
A review board for three teams. Click a tile, show the answer, add points. Edit the clue list and it reruns.

The whole game is one HTML page. The clues sit in a short list at the top of the code, so changing a question means changing one line, not rebuilding slides.

Make it with AI

Paste this prompt into ChatGPT, Claude or Gemini. Replace the parts in square brackets with your unit and grade.

Make a Jeopardy-style review game as ONE self-contained HTML file.
Topic: [your unit, for example fractions and decimals]. Grade: [level].
- 5 categories with 5 clues each, worth 100 to 500 points.
  Easier clues are worth fewer points.
- A grid of tile buttons. Clicking a tile opens a full-screen clue
  with a Show answer button.
- Three teams. After the answer, buttons add the points to a team,
  or close the clue with no points.
- Used tiles turn dark and cannot be clicked again.
- Very large text that can be read from the back of a classroom.
  It must also work on a phone.
- Keep every clue in one list at the top of the script.
- No external files, no images, no localStorage.
Write out every clue and answer. Do not use placeholders.

Before you use the result, check four things:

  1. Every clue and answer. Read them against your own materials. A model can state a wrong answer with full confidence.
  2. Ambiguous clues. If two answers could be right, rewrite the clue.
  3. Every tile. Click all of them once, including the last one, to make sure each opens and closes.
  4. Your phone. Open it on a phone as well as a computer.

If the page comes back blank or cut off, see AI HTML not rendering. For other kinds of games, see AI HTML game generator.

Copy the whole HTML from the chat, paste it into a NOS document, and choose Create share link. HTML to link walks through it. The page renders as written and its scripts run, so the tiles work.

Anyone with the link can open it in a browser, on a phone too, without an account. They can play it but not edit it. If you fix a clue later, edit the code and the same link shows the new version.

From the AI chat to a link on the class screen in four steps.
From the AI chat to a link on the class screen in four steps.

If your page came from Claude, how to share HTML from Claude covers that route.

Run a round on the class screen

Open the link on the computer that drives the projector or display. Keep that tab open for the whole game, because the board does not remember scores once the page is reloaded.

One turn: pick a tile, read the clue, show the answer, give the points.
One turn: pick a tile, read the clue, show the answer, give the points.

A turn takes four clicks. The tile you used turns dark, so nobody can pick it twice. If the back row cannot read the screen, ask the AI for larger clue text and paste the new version over the old one in NOS.

Make your own board from a list

Rewriting the code for every unit is slow. This second page reads its clues from a plain list instead. Each line is a category, points, a clue and an answer, separated by a vertical bar.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Board from a list</title>
<style>
  * { box-sizing: border-box; }
  body { margin: 0; min-height: 100vh; padding: 12px; font-family: system-ui, sans-serif; background: #0b1e5b; color: #fff; }
  .editor label { display: block; font-size: 14px; margin-bottom: 4px; color: #cfd8ff; }
  textarea {
    width: 100%; height: 150px; padding: 8px; border-radius: 6px; border: 0;
    font: 13px/1.4 ui-monospace, Consolas, monospace; color: #10204f; background: #f4f6ff;
  }
  .bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
  button { cursor: pointer; font: inherit; }
  .bar button, .row button {
    border: 0; border-radius: 6px; padding: 8px 14px; font-weight: 700; background: #ffd24a; color: #0b1e5b;
  }
  .bar button.quiet, .row button.quiet { background: transparent; color: #fff; border: 1px solid #8fa2e8; }
  .error { color: #ffb4a8; font-size: 14px; min-height: 1.2em; margin: 0 0 6px; }
  .board { display: grid; gap: 6px; }
  .cat {
    display: flex; align-items: center; justify-content: center; text-align: center; min-height: 44px; padding: 4px;
    background: #14308f; border-radius: 6px; font-weight: 700; text-transform: uppercase; font-size: clamp(11px, 2.2vw, 18px);
  }
  .tile {
    min-height: 60px; border: 0; border-radius: 6px; background: #1d4ed8; color: #ffd24a;
    font-weight: 800; font-size: clamp(18px, 4vw, 34px);
  }
  .tile:hover { background: #2a5ee8; }
  .tile:disabled { background: #162a6e; color: #162a6e; cursor: default; }
  .gap { background: transparent; }
  .scores { display: flex; gap: 8px; margin-top: 10px; }
  .team { flex: 1; text-align: center; padding: 6px; border-radius: 6px; background: #14308f; }
  .team b { display: block; font-size: 13px; font-weight: 600; opacity: .85; }
  .team span { font-size: clamp(20px, 4vw, 30px); font-weight: 800; color: #ffd24a; }

  .overlay {
    position: fixed; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 18px; text-align: center; background: #14308f;
  }
  .overlay.open { display: flex; }
  .overlay .tag { font-size: clamp(13px, 2.4vw, 20px); text-transform: uppercase; opacity: .8; }
  .overlay .clue { margin: 0; max-width: 900px; font-size: clamp(22px, 5vw, 44px); font-weight: 700; line-height: 1.25; }
  .overlay .answer { margin: 0; font-size: clamp(22px, 5vw, 40px); font-weight: 800; color: #ffd24a; min-height: 1.3em; }
  .row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
  [hidden] { display: none !important; }
</style>
</head>
<body>
<div class="editor" id="editor">
  <label for="src">One clue per line: Category | points | clue | answer</label>
<textarea id="src" spellcheck="false">Oceans | 100 | The largest ocean on Earth. | Pacific
Oceans | 200 | The ocean that lies around the North Pole. | Arctic
Oceans | 300 | The ocean between Africa and Australia. | Indian
Shapes | 100 | A shape with three sides. | Triangle
Shapes | 200 | The number of sides on a hexagon. | 6
Shapes | 300 | A four-sided shape with four equal sides and four right angles. | Square
Spelling | 100 | The plural of "child". | Children
Spelling | 200 | The past tense of "run". | Ran
Spelling | 300 | The silent letter at the start of "knife". | K</textarea>
</div>
<div class="bar">
  <button id="build">Build board</button>
  <button id="toggle" class="quiet">Hide editor</button>
</div>
<p class="error" id="error"></p>
<div class="board" id="board"></div>
<div class="scores" id="scores"></div>

<div class="overlay" id="overlay">
  <div class="tag" id="tag"></div>
  <p class="clue" id="clue"></p>
  <p class="answer" id="answer"></p>
  <div class="row" id="show-row"><button id="show">Show answer</button></div>
  <div class="row" id="award-row" hidden></div>
</div>

<script>
  const teams = ['Team A', 'Team B'];
  const $ = (id) => document.getElementById(id);
  let scores = teams.map(() => 0), current;

  function el(tag, text) {
    const e = document.createElement(tag);
    if (text !== undefined) e.textContent = text;
    return e;
  }

  // Turn the text box into categories, keeping the order you typed.
  function parse(text) {
    const cats = [], errors = [];
    text.split('\n').forEach((line, i) => {
      if (!line.trim()) return;
      const p = line.split('|').map((s) => s.trim());
      if (p.length < 4 || !p[0] || !p[2] || !p[3] || isNaN(parseInt(p[1], 10))) {
        errors.push('Line ' + (i + 1) + ' needs: Category | points | clue | answer');
        return;
      }
      let cat = cats.find((c) => c.name === p[0]);
      if (!cat) { cat = { name: p[0], clues: [] }; cats.push(cat); }
      cat.clues.push({ points: parseInt(p[1], 10), clue: p[2], answer: p[3] });
    });
    return { cats, errors };
  }

  function drawScores() {
    $('scores').replaceChildren(...teams.map((name, i) => {
      const box = el('div'); box.className = 'team';
      box.append(el('b', name), el('span', String(scores[i])));
      return box;
    }));
  }

  function build() {
    const { cats, errors } = parse($('src').value);
    $('error').textContent = errors.join('  ');
    if (!cats.length) { $('board').replaceChildren(); return; }
    const rows = Math.max(...cats.map((c) => c.clues.length));
    $('board').style.gridTemplateColumns = 'repeat(' + cats.length + ', minmax(0, 1fr))';
    const cells = cats.map((c) => { const h = el('div', c.name); h.className = 'cat'; return h; });
    for (let r = 0; r < rows; r++) {
      cats.forEach((c) => {
        const clue = c.clues[r];
        if (!clue) { const g = el('div'); g.className = 'gap'; cells.push(g); return; }
        const tile = el('button', '$' + clue.points);
        tile.className = 'tile';
        tile.addEventListener('click', () => openClue(tile, c.name, clue));
        cells.push(tile);
      });
    }
    $('board').replaceChildren(...cells);
    scores = teams.map(() => 0);
    drawScores();
  }

  function openClue(tile, category, clue) {
    current = { tile, clue };
    $('tag').textContent = category + ' for $' + clue.points;
    $('clue').textContent = clue.clue;
    $('answer').textContent = '';
    $('award-row').hidden = true;
    $('show-row').hidden = false;
    $('overlay').classList.add('open');
  }

  function closeClue() {
    current.tile.disabled = true;
    $('overlay').classList.remove('open');
  }

  $('show').addEventListener('click', () => {
    $('answer').textContent = current.clue.answer;
    $('show-row').hidden = true;
    const row = $('award-row');
    row.replaceChildren(...teams.map((name, i) => {
      const b = el('button', '+ ' + name);
      b.addEventListener('click', () => { scores[i] += current.clue.points; drawScores(); closeClue(); });
      return b;
    }));
    const none = el('button', 'No one'); none.className = 'quiet';
    none.addEventListener('click', closeClue);
    row.append(none);
    row.hidden = false;
  });

  $('build').addEventListener('click', build);
  // Hide the editor before you show the board: it lists every answer.
  $('toggle').addEventListener('click', () => {
    const hide = !$('editor').hidden;
    $('editor').hidden = hide;
    $('toggle').textContent = hide ? 'Show editor' : 'Hide editor';
  });
  build();
</script>
</body>
</html>
Type or paste lines, press Build board, then hide the editor before you show the class.

To keep your own questions in the shared link, put the lines inside the text box in the code, not on the page. What anyone types on the page is not saved, and reloading brings back the lines from the code.

You can also ask an AI for the list directly:

Write 20 lines for a review game on [topic], grade [level].
Format: Category | points | clue | answer
4 categories, points 100 to 500, one clue per line.

Paste the lines into the box and press Build board. The Hide editor button covers the answers while you project.

The same link works in several places. Pick the ones your class already uses.

Where What you do What people see
Class screen Open the link in a browser on the display computer The board with clickable tiles
Google Classroom In Classwork, choose Create, then Material, then Add, then Link A material with the link attached
Email or chat Paste the link into the message A link that opens in a browser
Paper handout Turn the link into a QR code with any QR code maker A code to scan that opens the same page
One share link, three places: the class screen, Google Classroom and a printed QR code.
One share link, three places: the class screen, Google Classroom and a printed QR code.

For Classroom, Google's help says to click Create and then Material, enter a title, click Add and choose Link, then click Post. For an assignment, choose Link under Attach, then click Assign.

Menus can change and differ by account type, so check Google's current help page, as of October 2026. For the paper version, see file to QR code.

When it does not work

What you see Cause Fix
Tiles do nothing when clicked The AI reply was cut off before the end of the script Ask for the complete file again, then paste it all
Scores went back to zero The page was reloaded or reopened Keep one tab open for the whole game
A picture is missing Images from other websites are blocked in NOS pages Ask for emoji, CSS shapes or inline SVG instead
Text is too small at the back The AI chose a small font size Ask for clue text of at least 40 pixels
Two answers fit one clue The clue was written loosely Edit that line in the code; the link stays the same
A student sees the old question Their tab still holds the earlier version Ask them to reload the page
Students can read the answers The answers are part of the page code Use it for review play, not for graded tests

Questions people ask

Do students need an account to open the board?

No. A link made with NOS opens in a normal browser, on a computer or a phone, without an account. Visitors can play the board but cannot edit the page.

Will the scores be saved if I close the page?

No. The example boards keep scores only while the page is open. Reloading or reopening the link starts a new game, so keep the class screen on the same tab for the whole round.

Can I change a question after I have shared the link?

Yes. Edit the clue in the code in NOS and the same link shows the new version. Anyone who already has the page open needs to reload it to see the change.

Can the AI write the clues too?

Yes, and it is quick, but check every clue and answer yourself before class. A model can write a clue that has two correct answers or a wrong answer, and it will not warn you.

Can students read the answers in the code?

Yes. The answers are part of the page, so a student who views the page source can read them. That is fine for a friendly review game, but do not use this for a graded test.

Keep reading