Blog · · 9 min

Claude Code product page: prompt or components?

A longer prompt improves the layout and leaves the section order and the missing mechanics exactly where they were, because with no constraint the model returns the arrangement it has seen most. A component is a decision already made and saved to a file. A prompt is an intention redrawn on every run.

By

Components, for the mechanics. Prompt, for everything else.

A better prompt genuinely improves things: the spacing, the copy, the typographic scale, the colour choices, whether the hero image is cropped sensibly. What it does not move is the order of the sections and the presence of the mechanics, and those are the two things that decide whether the page takes money. It does not move them because with no constraint a model returns the most common arrangement in its corpus, and asking for it in more words does not make a different arrangement more common.

The pivot is this. A component is a decision that has already been made and written to a file. A prompt is an intention, redrawn from scratch on every execution.

What does a short prompt return?

Build a product page for a 3-pack of specialty coffee. React and Tailwind.

You get a competent page. Gallery on the left, title and price on the right, a variant control, an add-to-cart button, a paragraph of description, a specifications block, a reviews section, a related-products row, a footer.

Nothing there is wrong. Everything there is the median, and the median is what a page looks like when nobody decided anything — a failure mode we took apart in why every AI generated landing page looks alike.

What does a longer prompt change?

Build a product page for a 3-pack of specialty coffee. React and Tailwind.

Brand: dark roast, industrial, not artisanal-cute. Near-black background,
one warm accent, Archivo for headings, tabular figures on all prices.
Mobile first, 390 px is the design target, the desktop layout is derived.
The price and the add-to-cart button must be reachable without scrolling
back up, at any scroll position, on mobile.
No stock photography, no rounded-everything, two radius scales not one.
Copy: second person, no exclamation marks, no words like premium or
elevate. Write the delivery promise as a date, never as a duration.

Now the output is genuinely better. Three or four of those constraints will land visibly, and the page stops looking like the sample.

Here is what moved and what did not:

Short promptLong prompt
Typography and colourDefaultsFollows your instruction
Spacing and rhythmUniformImproved
Copy toneGenericOn brief
Sticky mobile price and buttonAbsentPresent, because you named it
Section orderGallery, price, description, specs, reviewsSame
Quantity tier that makes the 3-pack the obvious pickAbsentAbsent
Delivery date rather than a durationAbsentPresent, because you named it
Amount remaining before free shippingAbsentAbsent
Complement offered after add-to-cartAbsentAbsent

Read the pattern in that table rather than the rows. Everything you named appeared. Nothing you did not name appeared. The long prompt is not smarter than the short one; it is longer, and the extra length is a list of things you already knew to ask for.

Which is the actual problem. The mechanics you are missing are, by definition, the ones you did not think to name.

![A letterpress lead slug, ink-stained and sharp-edged, lying on black steel under hard light beside a torn handwritten note, the slug reading ADD TO CART in reversed relief.](/blog/plomb-et-note.webp "Left, cast metal: the same impression every time it goes on the press. Right, a note someone re-reads and re-interprets. That is the whole difference between a component and a prompt.")

Why does the section order never move?

Because the order is not an aesthetic preference the model holds. It is a frequency.

In the corpus, the description follows the price and precedes the specifications, in an overwhelming number of pages. The model is not choosing that order; it is returning it. And a prompt that says make the page convert better provides no information about which order is better, so the model falls back on the same distribution and rewords the headings.

Test whether that is true rather than believing it. Run the same prompt five times and diff the results:

for i in 1 2 3 4 5; do
  claude -p "Build a product page for a 3-pack of specialty coffee, React and Tailwind" \
    > "run-$i.tsx"
done

# What differs between runs
diff run-1.tsx run-2.tsx | head -40

# What never differs: the skeleton
for f in run-*.tsx; do
  echo "--- $f"
  grep -oE '<(section|h2)[^>]*>' "$f" | head -12
done

The wording changes on every run. The class names change. The skeleton holds. That is the demonstration, on your machine, with your model, and it costs five minutes.

What does a frozen decision look like?

Take one small thing from the long prompt: write the delivery promise as a date, never as a duration. Delivered Thursday 11 September is a commitment a buyer can check against their week. Ships in 3 to 5 business days is arithmetic they have to run, badly, while holding a card.

As a prompt line, that instruction survives exactly as long as the prompt does. As a file, it is decided once:

const HOLIDAYS = new Set(['2026-12-25', '2026-12-26'])

function isWorkingDay(d: Date): boolean {
  const day = d.getDay()
  if (day === 0 || day === 6) return false
  const iso = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(
    d.getDate(),
  ).padStart(2, '0')}` // local date, not toISOString: that one is UTC
  return !HOLIDAYS.has(iso)
}

function addWorkingDays(from: Date, days: number): Date {
  const d = new Date(from)
  while (days > 0) {
    d.setDate(d.getDate() + 1)
    if (isWorkingDay(d)) days--
  }
  return d
}

export function deliveryLine(
  now = new Date(),
  { cutoffHour = 14, transitDays = 3, locale = 'en-US' } = {},
): string {
  const shipsToday = isWorkingDay(now) && now.getHours() < cutoffHour
  const dispatch = shipsToday ? now : addWorkingDays(now, 1)
  const arrival = addWorkingDays(dispatch, transitDays)
  const date = new Intl.DateTimeFormat(locale, {
    weekday: 'long',
    day: 'numeric',
    month: 'long',
  }).format(arrival)

  return shipsToday
    ? `Order within ${cutoffHour - now.getHours()} h, delivered ${date}`
    : `Delivered ${date}`
}

Read what is decided in there and cannot come out differently tomorrow: weekends are excluded, holidays are a list you control, the cutoff creates urgency only while it is genuinely true, the date is formatted in the buyer's locale rather than in yours, and the sentence degrades to a plain date once the cutoff has passed instead of inventing a countdown.

Six decisions. A prompt can carry them for one session. A file carries them for every page, every teammate, every model version.

So do you stop prompting?

No. You split the work by how much variance you can tolerate.

Use a prompt forUse a component for
Copy, tone, headline optionsAnything holding a price
Layout, spacing, visual hierarchyAnything holding a quantity
Colour, typography, imageryAnything a buyer computes with
One-off sectionsAnything with a legal constraint on it
Exploration, three versions to compareAnything you would be annoyed to lose next week

The line is not creative versus technical. It is variance. Where a different result on the next run is interesting, prompt. Where a different result on the next run is a bug, write the file.

There is a middle path worth knowing about: a project instruction file or a skill pins the constraints across sessions without hardening them into components, and what that approach reaches and where it stops is its own subject. It fixes repetition. It does not fix the mechanics you never knew to name.

And if the agent cannot see the page it produced, none of this is measurable anyway — the loop that closes that gap is in the MCP servers worth installing for frontend work.

uxgen exists to be the second column of that table: an MCP that hands the agent 168 commerce components as HTML the merchant keeps, from $19 a month. It has no paying customers yet. The four cart mechanics are MIT and readable now, no install: github.com/kinerette/uxgen-commerce-kit.

FAQ

Can Claude Code build a good product page from a prompt?

It builds a competent one, and a longer prompt makes it visibly better on typography, spacing, copy and layout. What a prompt does not change is the section order or the presence of selling mechanics, because those come back as the most common arrangement in the training corpus unless you name each one explicitly. Everything you name appears; nothing you leave unnamed does.

Why does every generated product page have the same section order?

The order is a frequency, not a preference. Gallery, price, description, specifications, reviews is overwhelmingly the most common sequence in the corpus, so a model with no constraint returns it and rewords the headings. Asking for a page that converts better supplies no information about which order converts better, so the fallback wins.

What is the difference between a prompt and a component?

Variance. A component is a decision written to a file: it produces the same result on every run, for every teammate, across model versions. A prompt is an intention that gets redrawn from scratch each execution, so the wording and the class names change while the skeleton stays the same. Use prompts where a different result is interesting and components where a different result is a bug.

Should the delivery promise be a date or a duration?

A date. Delivered Thursday 11 September is something a buyer checks against their own week; Ships in 3 to 5 business days is arithmetic they have to run while holding a card. Computing it means excluding weekends and holidays, applying a dispatch cutoff, and formatting in the buyer's locale — which is exactly the kind of six-decision detail that belongs in a file rather than in a prompt line.

uxgen is a service of UXGen AI, LLC — 131 Continental Dr, Suite 305, Newark, DE 19713, United States.

© 2026 UXGen AI, LLC. All rights reserved.