Passion Taste 3–4 hours Code Club · 02 of 02

Add Claude as the Brain

Take your page from project 03. Now make Claude do the smart parts. Without an API key. Generate the smart content in claude.ai chat, save it as a JSON file, your page reads it. The result: your page does something neither you nor Claude alone could.

In high school, kids connect to Claude through an API key + a server. That's powerful, but it's also a lot of setup, and a real cost-and-safety risk if a key gets leaked. There's a much simpler way that's used by most people who actually use Claude in their daily work: generate the content in claude.ai, save it, ship it.

This is exactly how a real journalist uses Claude to draft an article. Or how a designer uses Claude to suggest 20 color palettes. Or how a teacher uses Claude to make a quiz. The Claude part happens once, in chat. The result is saved. The product reads the saved result.

Why no API key?

API keys are like credit cards — if a key leaks, someone could rack up a real bill. Real engineers handle that with servers and security setup that's overkill for a 12-year-old's first project. The copy-paste workflow is simpler, safer, and powerful enough to do real things.

Step by step

  1. Pick the smart part of your page.

    Look at your project 03 page. Where does it currently use a hard-coded list (like the books in the Owen example)? That's the part Claude can replace — but smarter. Owen's books were 3–7 books per vibe. Claude can generate 30 books per vibe, with a personal note for each, in 30 seconds.

  2. Open claude.ai and write a real system prompt.

    Don't ask "give me 30 books." Ask with structure: who's the user, what do they like, what's the output shape. The prompt is the most important file in this whole project. See the worked example.

  3. Ask Claude to output JSON.

    JSON is just a structured way of writing data. {"weird-scifi": ["book1", "book2"]}. Once Claude returns JSON, your JavaScript can read it like a database.

    Crucial: tell Claude "return only the JSON, no other text". Otherwise it adds a friendly intro you don't want.

  4. Save the JSON to a file in your folder.

    Copy the JSON from Claude. Paste it into a new file called data.json in your project folder. Save.

  5. Make your JavaScript load the file.

    Replace your hard-coded book list with a fetch('data.json') call. JavaScript reads the file. Now your page is reading data Claude generated.

  6. Re-deploy. Demo to your named user.

    Drag the folder to Netlify Drop again. Get the new URL. Hand it to your friend. "This time the books are picked by Claude — but tuned for you." Notice their face.

A complete worked example

The Owen book picker, leveled up. The Claude prompt, the JSON output, the JavaScript change.

copy this into claude.ai (or claude.com)
I'm building a book recommendation page for my brother Owen,
age 13. I need you to generate a JSON file of 30 books across
3 vibes. About Owen:

  - reads weird sci-fi (VanderMeer, Strugatsky, Le Guin)
  - reads narrative history that reads like a novel (Grann, Lansing)
  - reads graphic novels with strong art (Saga, Persepolis)
  - actively dislikes YA fantasy unless the prose is sharp
  - tried Stephen King twice, didn't stick — don't suggest him

Output: a JSON object exactly in this shape (no other text,
no explanation, just the JSON):

{
  "weird-scifi": [
    {"title": "...", "author": "...", "why": "one sentence
      on why it's right for Owen specifically"},
    ... 10 entries
  ],
  "real-history": [ ... 10 entries ],
  "graphic": [ ... 10 entries ]
}

Important: the "why" field is the part where YOU are doing
work. Make it specific. Don't say "exciting and fun" — name
something Owen specifically would like. Use the things you
know about him from the bullets above.
data.json · what Claude returns (you save this file)
{
  "weird-scifi": [
    {
      "title": "Annihilation",
      "author": "Jeff VanderMeer",
      "why": "starts ordinary, ends with the rules of reality slightly broken in a way Owen will feel before he can name"
    },
    {
      "title": "Piranesi",
      "author": "Susanna Clarke",
      "why": "narrator slowly realizes something is wrong with his world; Owen's exact pace as a reader"
    },
    {
      "title": "Roadside Picnic",
      "author": "Strugatsky brothers",
      "why": "the original 'mysterious zone' book — way shorter than Owen expects, ending stays with you"
    }
  ],
  "real-history": [
    {
      "title": "The Wager",
      "author": "David Grann",
      "why": "shipwreck, mutiny, court-martial — pages turn themselves; Grann is Owen's kind of writer"
    },
    {
      "title": "Endurance",
      "author": "Alfred Lansing",
      "why": "Shackleton in Antarctica, no one dies, somehow more impossible than fiction"
    }
  ],
  "graphic": [
    {
      "title": "Saga, vol. 1",
      "author": "Brian K. Vaughan",
      "why": "the art does work the prose can't — start here, the rest of the series follows"
    },
    {
      "title": "Persepolis",
      "author": "Marjane Satrapi",
      "why": "memoir, black and white, the kind of book that stays with Owen two years later"
    }
  ]
}
script.js · loads data.json instead of hard-coding
// load the Claude-generated data file when the page opens
let BOOKS = null;

fetch('data.json')
  .then((r) => r.json())
  .then((data) => {
    BOOKS = data;
    // we're ready — you could enable the buttons here
  })
  .catch((err) => {
    document.getElementById('result').innerHTML =
      '<p style="color:#B43D2C">Could not load books. Check that data.json is in the same folder.</p>';
  });

// when a button is clicked, pick from BOOKS (which Claude wrote)
const buttons = document.querySelectorAll('.vibe');
const result = document.getElementById('result');

buttons.forEach((btn) => {
  btn.addEventListener('click', () => {
    if (!BOOKS) {
      result.textContent = 'Still loading…';
      return;
    }
    const vibe = btn.dataset.vibe;
    const list = BOOKS[vibe];
    const pick = list[Math.floor(Math.random() * list.length)];
    result.innerHTML = `
      <h2>${pick.title}</h2>
      <p style="color:#4D5266">by ${pick.author}</p>
      <p>${pick.why}</p>
    `;
  });
});

Live demo 1: how the prompt's shape changes Claude's output

Most kids ask Claude vaguely and get vague answers. The trick is in the shape of your prompt: a named user, specific preferences, and an exact output format. Try the two prompts side-by-side.

Prompt-shape demo


Live demo 2: is your JSON valid?

One missing comma and your page won't load anything. Paste Claude's output here. The widget tells you if it's clean JSON or what's broken.

JSON checker

What makes this hard

Claude often adds an intro sentence. "Here's the JSON you asked for: { ... }" — that intro breaks the parser. Tell Claude in the prompt: "Return ONLY the JSON, no other text, no markdown."

One typo breaks the whole file. JSON is unforgiving — a missing comma, a stray quote inside a string, an extra closing brace. Use the JSON validator above on Claude's output before you save the file. (If you forget, your page will load with no books and you'll spend an hour wondering why.)

fetch only works from a server. If you double-click index.html on your computer, fetch('data.json') may fail because of browser security. Either deploy to Netlify Drop (it just works there) or run a local server: in your folder, run python3 -m http.server in the terminal.

Self-check before you ship

  • The system prompt I sent to claude.ai has a named user, specific preferences, and a strict output format.
  • Claude returned only JSON, no intro sentence.
  • The JSON passes the validator (no missing commas, all strings closed).
  • data.json is saved in the same folder as index.html.
  • script.js uses fetch() to load it, with a try/catch (or .catch) for the error case.
  • The page works at the deployed Netlify URL — not just on my computer.
  • The named user has tried v2 and noticed at least one suggestion that surprised them.

Try it · once your Claude-powered page is live

Static JSON is the floor. Want to push?

  1. Refresh the recommendations weekly. Once a week, paste the same prompt back into claude.ai. Get a new data.json. Replace the old one. Re-deploy. Your friend's recommendations are now fresh — and you didn't write a single new line of code.
  2. Add a "why this is good" section to the page. Right now your page shows the title and the why-line. Add a second line: "This recommendation was made by Claude, tuned for [name]." Be transparent. Real adults appreciate when AI work is labeled honestly.
  3. Make a second JSON file for a different person. Same code, different file. data-owen.json, data-mei.json. Pick which file to load based on a URL parameter. Now one page can serve two named people. This is the same trick that powers half of all real personalization on the internet.