Skip to main content
Episode 8 of 24Storefront50 min

Build the catalogue: categories, search and product pages

Show your products from the local database with category pages, filters, search, detail pages, search-engine metadata and structured data.

You will have: Working category, listing, search and product pages that read from the Postgres seed data, with page titles, descriptions and Product structured data ready for Google.

Before you start

  • Episode 7 is merged: the design system, layout and home page exist
  • The local database shop_local is running and the seed data from Episode 6 is loaded (if it is thin, the agent will add more)
  • A list of your real product groups, filter ideas (size, color, price) and a few product names to use as examples
  • You are on the main branch with a clean working tree

Make it yours

Change the example (a fashion store) to your own. Your answers are saved in this browser and used in every episode.

Other series keywords (4)

Your prompt

Paste into: {{ai_agent}} opened in your project folder.
You are a senior full-stack developer working inside my Next.js (App Router), TypeScript, Tailwind and Drizzle project for "Thread & Needle", a fashion e-commerce store selling women's and men's clothing, shoes and accessories to customers in United States. Prices are in USD. I am not a programmer, so explain technical words briefly.

Goal: build the public catalogue, reading real data from the local Postgres database shop_local using the tables and seed data from Episode 6. Do not build the cart, accounts or checkout yet.

Plan first: inspect the current database schema and seed data, then show me your plan (routes, tables you will add or change, filters, and how URLs will look) and wait for my OK before changing anything. If the schema is missing something the catalogue needs (categories, products, variants such as size or color, stock, image slots), propose the change as a drizzle-kit migration, never a manual edit.

Tasks, after I approve:
1. Create a branch named feature/catalogue.
2. Make sure the data model has: categories (with slug and parent), products (slug, name, description, price in whole minor units, status active or draft, created date), variants (option values, stock, optional price), and image records that hold a public id and alt text for later (Episode 9 fills them). Add database indexes for slug, category and status. Extend the seed so there are at least 12 products across 3 categories, including one out of stock item and one draft item that must never show.
3. Build routes: shop (all products), shop by category, product detail by slug, and search. Use readable URLs.
4. Listing pages: product grid using the Episode 7 components, sorting (newest, price low to high, price high to low), filters (category, price range, in stock, plus one or two filters that suit women's and men's clothing, shoes and accessories), and pagination. Keep filter state in the URL so pages can be shared and bookmarked.
5. Search: a search box in the header and a results page. Use parameterized queries only, escape special characters, and show a friendly empty state with suggestions.
6. Product page: gallery slots with a placeholder image, name, price, description, variant picker, stock message (in stock, low stock, sold out), and a disabled Add to cart button with a note that the cart arrives in Episode 10. Return a proper 404 for unknown or draft products.
7. SEO: generateMetadata for every page with a unique title, description, canonical URL based on threadandneedle.com and Open Graph tags; JSON-LD structured data for Product (name, description, image, offers with price, currency and availability) and BreadcrumbList; a heading structure with one h1.

Security rules:
- Validate every query parameter with Zod and ignore or reject bad values; never trust the URL.
- Only status active products are ever returned to the public.
- When writing JSON-LD into the page, escape the less-than character so product text cannot break out of the script tag.
- Do not log or print any database URL or secret.

Verify by running these yourself and showing the results: type check, lint, production build, and a script or test that loads the main pages and confirms that the draft product is absent, the sold-out product is labeled, a bad filter value does not crash the page, and the JSON-LD parses as valid JSON.

Commit in small steps with clear messages, push the branch and open a pull request.

Report back in this format:
1. What you did.
2. What I should check myself (URLs to open).
3. Anything that needs my decision.

Review the prompt, then copy it. Never paste real passwords or API keys into a chat.

How to check it worked

  • Open the shop page and see the seeded products in a grid, with the draft product missing
  • Click a category, then change sorting and a filter: the address bar changes, and copying that address into a new tab shows the same result
  • Search for a word from a product name and for nonsense: the first shows matches, the second shows a friendly empty message
  • Open a product page: you see name, price, variant picker and a stock message; a made-up address shows a proper not-found page
  • Right-click a product page and choose View page source, then search for application/ld+json: you find the Product data with the right price and currency
  • The agent's report shows a successful build and a passing page check

Sample result

Fashion store example

Example result for the fashion store: a category page with filters, and the agent's check of structured data.

If something goes wrong

The pages are empty or show a database error.
Make sure local Postgres is running, then ask: "Check the database connection and that the seed ran, without printing the connection string, and fix what is missing."
The agent wants to change the database by hand or delete data.
Say no and repeat the rule: all schema changes go through drizzle-kit migrations. On a local database you can always re-run the seed, but never point this work at the production database.
A filter shows the wrong products or the count looks wrong.
Ask the agent to write a test for that exact filter with a small known data set and to fix the query until the test passes.
Google's Rich Results Test is not available for your local site.
That is normal; it needs a public address. For now rely on the agent's JSON-LD check and test again after deployment in Episode 21.

More in Storefront

This is part of the series Build a secure, no-cost e-commerce website with AI agents. See all 24 episodes, the tools used and answers to common questions on the series page.

We use optional cookies for analytics and referral tracking. Learn more about our privacy policy