Foundations · Lesson 07 — Building your first simple web page with Claude
F07Foundations
Foundations · Lesson 07● live

Building your first simple web page

Project scaffold, dev server, iterate-by-screenshot — end-to-end.

20 min read · 60 min applyprereq: none — start here if you've never shipped a page

What we’re building

One page. Hero, three feature cards, CTA, footer. Locally served by a dev server. Deployable to Vercel or Netlify with two clicks. Total time: 60-90 minutes if it’s your first time, 20 minutes after the second.

The point isn’t the page. The point is the loop — how you brief, scaffold, iterate, and ship a real artifact with an agent. The same loop scales to multi-page sites, dashboards, internal tools, and product UIs. The only thing that changes is the size of the brief and the count of screenshots.

If you’ve never run a dev server, never edited a JSX file, never deployed anything — this lesson is the right starting point. The agent does the heavy lifting; you do the looking.

The scaffold + dev server, in one paragraph

Modern web frameworks ship a one-line scaffold command that creates a working project with a default homepage. For Next.js, it’s npm create next-app@latest with a few flags. The agent runs the command, you confirm the dev server is running by visiting http://localhost:3000, and from that point on every edit shows up in your browser the moment you save the file.

The dev server is the iteration medium. Edit a file, save, the browser reloads with the new state. This is what lets the screenshot loop work — the gap between “agent edited” and “you see the result” is one keystroke and one second. Without that loop, agent-built UI is guesswork.

  • Default scaffold flags: TypeScript on, Tailwind on, App Router on, ESLint off (we’ll add it later if needed)
  • Dev server command: npm run dev from the project folder
  • What to look for: “Ready in X.Xs” in the terminal, default welcome page at localhost:3000

Three ways the first build fails

The patterns that turn a 30-minute build into a three-hour fight. Hover any card to see the diagnosis.

01

The scaffold drift

claim looks likeAgent runs `npm create next-app` with one set of flags. Six prompts later it's offering to switch you to a different framework or add packages you didn't ask for.
what’s missingNo locked stack. The agent is reading the most recent best-practice it knows and trying to upgrade you mid-build, which churns the project and breaks earlier instructions.
the movePin the stack at scaffold time. "Next.js 16, TypeScript strict, Tailwind v4, no other dependencies unless I explicitly approve." Repeat in the CLAUDE.md so every session starts with the same constraints.
02

The blind iteration

claim looks likeYou ask for a layout change. Agent makes 3 file edits. You refresh the browser; it's wrong in a way the agent can't see and you can't describe well.
what’s missingNo screenshot loop. The agent is editing in the dark — it can't see what its changes produced, so it can't course-correct. You're translating visuals to words badly.
the moveTake a screenshot, paste it back to the agent, say "this is what your edit produced — what I want is X." The agent can see the diff between intended and actual and propose the next edit precisely.
03

The phantom feature

claim looks likeAgent says "I added a contact form." The form renders. Submitting it does nothing — no API route, no validation, no success state.
what’s missingNo explicit definition of done. The agent shipped the visible part because that's what "adding a contact form" looked like. The behavior layer was never specified.
the moveDefine done at the brief: "contact form means: renders, validates 3 fields, submits to /api/contact, shows success message, errors on failure." The agent ships all five or surfaces what it skipped.

The fix in all three: locked stack, screenshot loop, explicit definition of done. Without these, the agent improvises in the dark and the build drifts. With them, the build converges in 5-10 short loops.

The screenshot loop

The diagnostic is one prompt — pasted at the start of the build session. After scaffold, every revision happens through this loop until the page matches the brief.

The screenshot loop
We're going to iterate on this page by screenshot.

Each turn:
1. I make changes (or you propose them)
2. I refresh the dev server
3. I paste a screenshot of the current state
4. You tell me, in one short paragraph:
   - What you see vs what you expected
   - The specific element that's wrong (if any)
   - The smallest edit that would fix it

Don't propose multi-file refactors mid-loop. One issue,
one edit, screenshot, next. We're done when the screenshot
matches the brief.

The single move that prevents "agent edits in the dark" — agent sees actual output, not its own intent.

Most operators try to describe visual issues in words. Don’t. Words for visual issues are slow and lossy. Screenshots are precise. The agent reads the screenshot, identifies the specific element that’s wrong, proposes the smallest possible edit. Three loops gets you to a publishable page; ten loops gets you to a polished one.

Annotated transcript

A real conversation: operator scaffolds a Next.js landing page, hits a grid layout bug, fixes it via screenshot loop. Click any pinned annotation to expand the “why this turn matters” commentary.

From scaffold to first revision in 6 turns

Three operator turns, three agent turns. Result: working dev server, structure shipped, one layout bug found and fixed via screenshot.

  1. operator

    I want to build a simple landing page for my new tool. One page, hero section, three feature cards, a CTA, a footer. I've never built a Next.js app before.

  2. agent

    Two pins before we scaffold:

    1. Stack lock — I'll use Next.js 16, TypeScript strict, Tailwind v4, no other dependencies unless you approve. I'll add this constraint to your CLAUDE.md so every future session inherits it.
    2. Definition of done — "landing page" means: hero with headline + subhead + primary CTA, three feature cards in a grid, footer with links, mobile-responsive at 720px, deploys cleanly to Vercel or Netlify. Confirm or correct.

    After the pins I'll scaffold, start the dev server, and we'll iterate by screenshot.

  3. operator

    Confirmed on both. Go.

  4. agent

    Scaffolding now.

    npm create next-app@latest my-landing -- --ts --tailwind --app --no-eslint --no-src-dir --turbopack
    cd my-landing
    npm run dev

    Dev server is running at http://localhost:3000. You should see the default Next.js welcome page. Take a screenshot and paste it back — I want to confirm what you're seeing matches what I expect before I edit anything.

  5. operator

    [pastes screenshot of default Next.js welcome page]

  6. agent

    Scaffold confirmed. Now I'll replace app/page.tsx with the landing page.

    First pass — I'll write the structure (hero, three cards, footer) with placeholder copy. After you screenshot, we'll iterate on copy and styling separately. Splitting structure from style is the fastest loop.

    [delivers ~80 lines of TSX with hero, feature grid, footer; uses Tailwind utility classes for layout]

    Save and refresh. Screenshot back when you have it.

  7. operator

    [screenshot — page renders, layout works, but feature cards are stacked vertically on desktop instead of in a grid]

  8. agent

    I see it — the cards container needs md:grid-cols-3 but I wrote grid-cols-3 which only kicks in if the parent is a grid. The cards are using flex-column instead.

    One-line fix in app/page.tsx:

    - <div className="flex flex-col gap-6">
    + <div className="grid gap-6 md:grid-cols-3">

    Refresh and screenshot. If it's right, we move to copy.

Build brief template — copy and paste

Save in a snippets file. Paste before any web-build session. Customize the goal and the definition-of-done; the stack lock and screenshot-loop sections are reusable.

Build brief: <one-line description of what we're building>

GOAL
----
<2-3 sentences: who this is for, what it does,
where it lives>

STACK (locked)
--------------
- Next.js 16 (App Router, Turbopack)
- TypeScript strict
- Tailwind v4
- No other dependencies without my approval

DEFINITION OF DONE
------------------
- <visible element 1: e.g. "hero with headline + subhead + CTA">
- <visible element 2>
- <visible element 3>
- <interactive: e.g. "form validates 3 fields, submits, shows success">
- <responsive: e.g. "mobile-friendly at 720px breakpoint">
- <deploy: e.g. "deploys cleanly to Netlify, no console errors">

PROCESS
-------
- You scaffold + start dev server
- I confirm with screenshot before any edits
- Iterate structure-first, style-second
- One issue per screenshot loop
- Walk the definition-of-done before declaring shipped

The definition of done is the most-skipped section and the one that matters most for first builds. Without it, “done” is whatever the agent renders and you eyeball-approve. With it, “done” is checkable.

Prompt kit

Three prompts for scaffolding, locking the stack, and defining done. Save in your CLAUDE.md or a personal snippets file.

The screenshot loop
We're going to iterate on this page by screenshot.

Each turn:
1. I make changes (or you propose them)
2. I refresh the dev server
3. I paste a screenshot of the current state
4. You tell me, in one short paragraph:
   - What you see vs what you expected
   - The specific element that's wrong (if any)
   - The smallest edit that would fix it

Don't propose multi-file refactors mid-loop. One issue,
one edit, screenshot, next. We're done when the screenshot
matches the brief.
Lock the stack
Add this section to my CLAUDE.md so every session
inherits the same stack constraints:

## Stack (locked)
- Framework: Next.js 16 (App Router, Turbopack)
- Language: TypeScript strict
- Styling: Tailwind v4
- No other dependencies without explicit approval
- No framework upgrades or migrations without explicit approval
- No "best practice" rewrites of working code

If you think a new dependency or framework change is
warranted, surface it as a question. Don't add it
unilaterally.
Define done before coding
Before writing any code for <feature>, draft the
definition of done as a 5-7 item checklist:

- Visible behavior (what the user sees)
- Interactive behavior (what the user can do)
- Validation / error states
- API or data dependencies
- Mobile / responsive behavior
- Accessibility minimum (keyboard, alt text)
- Deploy condition (lints, type-checks, builds)

Show me the checklist. I confirm or correct. Only then
do you write code. After delivery, we walk through the
checklist together — you mark each item done or surfaced.

Apply this — your first real page

60-90 minute exercise. One page. Locked stack. Screenshot loop. Walk the checklist.

Your first agent-built page

Each step takes 10-20 minutes. Progress saves automatically.

0/5
  1. 01Pick the simplest real page you'd actually use. Personal landing, project page, link-in-bio. One page.Don't pick the dream project. Pick the page you'd link from your email signature next week.
  2. 02Lock the stack in your CLAUDE.md before scaffolding.Use the second prompt in the kit. Five minutes now saves an hour of framework drift later.
  3. 03Have the agent scaffold and start the dev server. Screenshot the default page back before any edit.This catches scaffold failures early. If the dev server isn't running, fix that before you touch any file.
  4. 04Iterate structure-first, style-second. One issue per screenshot loop.Don't ask for "make it look better." Ask for "the cards should be 3-across on desktop." Specific issues, surgical edits.
  5. 05Walk the definition-of-done checklist before declaring shipped.If any item was skipped, the agent surfaces it. You decide whether to ship anyway or close the gap.
Foundations tier · what's next

After this lesson