Building AI Features in React

What You Will Build: ShopLens


A product page for the Kestrel X2 wireless headphones has 214 reviews and an average of 4.1 stars. Almost nobody reads 214 reviews. Most shoppers read the first three, glance at the stars, and either buy or leave. The useful information, such as "the battery is great but the ear cushions get hot after two hours", is buried on page nine.

In this course you build ShopLens, a review-insights panel that sits on that product page and tells a shopper, in about ten seconds, what the buyers actually think. It is a small product, but it contains almost every problem you will meet when you put a model behind a real UI: output that has the wrong shape, answers that take seconds, text that is fluent but false, and a bill that grows with every page view.

This lesson shows you the finished panel first, so you always know where each later lesson fits.

One path for all three ShopLens featuresComponentcalls its hookTyped clientposts ids onlyBFF loadsreviews,builds the promptModel call withthe server's keyValidate, thenstream or returnThe browser never holds the key, the prompt or the review text.
Badge, summary and table share one path, so validation and cancellation are fixed once for all three.

The panel, feature by feature

Here is the finished panel, drawn as text:

Text
+------------------------------------------------------------+| What buyers say                                    [Stop]  || Most buyers praise the battery, which lasts a full work    || week for many [r1042]. Comfort is mixed: several find the  || cushions warm after two hours [r0988] [r1107]. A few ...   ||                                                            || Compare with: [ Wren Air  v ]                              ||  Aspect        | Kestrel X2        | Wren Air              ||  Battery       | 20+ hours, praised| 14 hours, complaints  ||  Comfort       | warm after 2 h    | light, praised        ||                                                            || Reviews                                                    ||  ***** "Best battery I have owned"            [Positive]   ||  ***   "Great sound, hot ears"                [Mixed]      |+------------------------------------------------------------+

ShopLens has three features, and you build them in this order:

  1. The sentiment badge. Each review gets a small label: Positive, Mixed or Negative. The output is tiny, the calls are many, so it uses a small, fast model and classifies a whole page of 20 reviews in one call.
  2. The "what buyers say" summary. Three or four sentences that stream in word by word, with a Stop button, a hard length limit and citations back to real reviews.
  3. Compare two products. The shopper picks a second product and gets a table of up to six aspects, such as battery and comfort, with what buyers say about each product.

Throughout the course we use two example prices: a small, fast model at $1 per million input tokens and $5 per million output tokens, and a larger model at $5 and $25. These match real models at the time of writing; check your provider's price page before you budget. A token is roughly three quarters of an English word.

FeatureOutput shapeModelTypical timeCost per call
Sentiment badgeJSON, 20 labelssmallabout 1.5 sabout $0.004
Buyer summarystreamed text, max 80 wordslargerfirst words in under 1 s, done in about 3 sabout $0.02
Compare tableJSON, up to 6 rowslargerabout 5 sabout $0.04

Those costs come from simple arithmetic. The summary sends the 40 most helpful reviews, about 3,600 input tokens: 3,600 × $5 / 1,000,000 = $0.018. It writes about 110 output tokens: 110 × $25 / 1,000,000 = $0.00275. Together that is about two cents, which is cheap once and expensive fifty thousand times a day. Section 5 deals with that.

The path of one request

Every ShopLens feature follows the same path. Learn it once and the three features become variations.

  1. Component — <BuyerSummary> mounts and calls the hook useStreamingSummary("p-310").
  2. Typed client — the hook calls streamText("/api/summary", ...) from src/api/client.ts, passing an AbortController signal.
  3. Backend-for-frontend (BFF) — an Express route validates the request, loads reviews for p-310 from the database, and builds the prompt.
  4. Model — the BFF calls the model with its secret key and a token limit.
  5. Back through the BFF — the BFF checks the output (length, shape, citations) and streams or returns it.
  6. State and render — the hook updates a small state machine and the component renders the right state.

Notice what the browser sends: a product id. It never sends review text, a prompt or a key. That single decision, explained in the fourth lesson of this section, removes a whole class of security and cost bugs.

What stays the same, and what changes

You do not need a new framework. ShopLens is plain React 18, TypeScript, fetch, and Zod for runtime validation. The server is a small Express app. What changes is the set of assumptions your code can make about the data it receives.

What stays the same

  • Components, props, hooks and state
  • fetch, JSON and HTTP status codes
  • TypeScript types across the codebase
  • Accessibility and performance work

What changes

  • The shape is unknown until you validate it
  • Responses take seconds, not milliseconds
  • The content can be wrong while sounding right
  • Every call costs real money

The course map

SectionWhat you add to ShopLens
1. How AI changes the frontendThe mental model: what breaks, why a BFF, what streaming is
2. Prompting for UI-ready outputPrompts that return short text and JSON your components can render, checked with Zod
3. Building AI features in ReactThe BFF, the typed client, all three features, and a request state machine
4. UX patterns for uncertaintyFast-feeling loading, honest confidence and sources, regenerate and feedback, graceful failure
5. Safety, cost and shippingPrompt injection and XSS defences, caching and deduping, tests for streams and states

Each lesson adds one piece. The file names stay the same from lesson to lesson: server/llm.ts, server/routes/summary.ts, shared/schemas.ts, src/api/client.ts, src/hooks/useStreamingSummary.ts and so on. By the end of section 3 the whole panel runs; sections 4 and 5 make it something you can ship.

Check your understanding

0 of 2 answered

1.The summary sends 40 reviews of about 90 tokens each to the larger model ($5 per million input tokens) and gets 110 tokens back ($25 per million output tokens). Roughly what does one summary cost?

2.In the ShopLens request path, what does the browser send to the server for the summary?