Building a Ten-Page E-Commerce Site: A Practical Evaluation Guide for AI Coding Tools

    This article explains why building a ten-page e-commerce site is a reliable benchmark for evaluating AI coding tools. It covers requirement specifications, routing and data contracts, single-shot versus multi-step generation, a scoring checklist, data-layer decoupling, AI-assisted bug fixing, engineering pipeline integration, production readiness, and how to build an internal evaluation baseline.

    1. Why a Ten-Page E-Commerce Site Is a Valid Evaluation Task

    When evaluating AI coding tools, one of the most common mistakes is to test them with isolated tasks such as “write a login form” or “implement a carousel.” These tasks may produce impressive-looking results, but they rarely reflect how the tool performs in a real project. The cost of a real project is usually not in a single component, but in cross-page consistency and correct state transitions.

    A typical e-commerce site covers both challenges well. A ten-page example can include:

    1. Home page / product list
    2. Product detail page
    3. Checkout page
    4. Purchase success page
    5. Login page
    6. Registration page
    7. Account overview page
    8. Account order list page
    9. Account wallet / coupon package page
    10. Account settings page

    Such a site also requires:

    • routing and nested layouts;
    • login state and authentication guards;
    • data passing from list pages to detail pages;
    • cross-page state management from cart to checkout;
    • form validation and error feedback;
    • visual consistency across multiple pages;
    • responsive behavior on both mobile and desktop.

    If any of these areas is implemented superficially, users will quickly sense that the result is “a demo, not a product.”

    Therefore, the evaluation focus should shift from “does the page look good?” to “is the site complete, consistent, and maintainable?”

    2. Upgrade a One-Sentence Prompt into a Requirement Specification

    In many cases, poor results come from prompts that only provide a list of pages without constraints. When information is missing, AI coding tools tend to fill in the gaps automatically. Their default choices are often:

    • mobile-first layout;
    • placeholder images everywhere;
    • data hard-coded directly inside components;
    • detail pages containing only a title, price, and short description.

    Before formal generation, it is better to produce a lightweight requirement specification. At minimum, it should contain four parts.

    2.1 Route and Page Responsibility Table

    1. / Home / product list (filter, sort, pagination)
    2. /product/:id Product detail (gallery, SKU, stock, review summary)
    3. /checkout Checkout (address, shipping, payment selection, amount summary)
    4. /checkout/success Purchase success (order number, next steps)
    5. /login Login
    6. /register Registration
    7. /account Account overview (quick links + recent orders)
    8. /account/orders Order list (status labels, actions)
    9. /account/wallet Wallet / coupon package (balance, coupon list, expiration)
    10. /account/settings Settings (profile, password, notifications, privacy)

    The value of a route table is that it turns “completeness” into a checkable list instead of something that must be judged visually.

    2.2 Define the Data Contract First

    Before generating any page, ask the tool to output type definitions first. This step has a major impact on downstream consistency:

    1. // types/domain.ts
    2. export interface Product {
    3. id: string;
    4. title: string;
    5. price: number; // Unit: cents, to avoid floating-point errors
    6. currency: 'CNY';
    7. coverUrl: string;
    8. images: string[];
    9. stock: number;
    10. tags: string[];
    11. summary: string;
    12. }
    13. export interface CartItem {
    14. productId: string;
    15. sku: string;
    16. qty: number;
    17. }
    18. export interface Order {
    19. id: string;
    20. status: 'pending' | 'paid' | 'shipped' | 'done' | 'canceled';
    21. totalAmount: number;
    22. createdAt: string;
    23. items: Array<{ productId: string; title: string; qty: number; price: number }>;
    24. }
    25. export interface Coupon {
    26. id: string;
    27. name: string;
    28. threshold: number; // Coupon threshold, unit: cents
    29. discount: number;
    30. expireAt: string;
    31. }

    With a clear data contract, every page should be implemented according to the same types. This significantly reduces visual and field drift.

    2.3 Design and Style Conventions

    Define design tokens explicitly so that each page does not invent its own style:

    • one primary color and semantic colors for success, warning, and error; do not hard-code color values inside components;
    • a spacing scale, such as 4 / 8 / 12 / 16 / 24 / 32;
    • border radius and shadow levels;
    • breakpoint definitions, such as 640 / 960 / 1280;
    • a font family and font size scale.

    2.4 Explicit Prohibitions

    This part is often overlooked, but it provides the highest return. Prohibit the following:

    • inline mock data;
    • placeholder images as the final solution;
    • empty files and empty directories;
    • duplicate directories with the same name;
    • adding dependencies that were not agreed upon;
    • mixing styles and logic in the same place.

    3. Trade-offs Between Two Generation Modes

    Most AI coding tools provide two main working modes. Understanding their differences is more valuable than memorizing product names.

    3.1 One-Shot Whole-Project Generation

    The tool generates the entire project within a single task.

    The main advantage is strong overall consistency. The directory structure, style, and component naming are usually unified, and you can quickly obtain a runnable skeleton.

    The limitation is that the context budget is limited. As the number of pages increases, later pages often become compressed “lightweight versions.” Typical symptoms include thin product detail pages, placeholder-only images, or an order page that contains only an empty list.

    This mode is suitable for:

    • project initialization;
    • scaffolding;
    • prototype validation.

    3.2 Step-by-Step Planning and Building

    In this mode, the tool first creates a task plan and then implements each task step by step. It is easier to control, easier to review manually, and easier to insert human review at intermediate stages.

    However, two common side effects can appear:

    • Style drift: page 1 uses component A, while page 7 introduces component B to implement a similar function, causing duplicated implementations.
    • Structural disorder: duplicate nested directories appear, or leftover empty shell files remain. For example, placeholders for hooks, state management, or context may be created, but their contents are empty. This can eventually lead to build failures or unpredictable behavior.

    This mode is suitable for:

    • feature iteration;
    • bug fixing;
    • completing pages one by one according to requirements.

    A practical approach is:

    1. Use one-shot generation to obtain a skeleton, data contract, and style baseline.
    2. Review the result manually.
    3. Switch to step-by-step mode to complete pages one by one.
    4. Perform a final consistency pass.

    This hybrid strategy usually reaches a usable state faster than relying on a single mode for the entire process.

    4. Turning Subjective Experience into a Scored Checklist

    When evaluating AI-generated output, it is useful to fix the following dimensions and score them during every regression round.

    Dimension Check Method Common Failure Symptoms
    Buildability Install dependencies, run the build, and run type checking. There should be no errors or blocking warnings. Duplicate nested directories, missing files, duplicated routes
    Runnability After starting the app, check for console errors and missing assets, such as 404 responses. White-on-white buttons, broken images
    Page completeness Visit every route in the route table. All 10 pages should be reachable. Missing account subpages, or pages merged together incorrectly
    Visual consistency Sample five pages and check primary color, spacing, and border radius. Random colors, inconsistent card styles
    Responsive behavior Check at 375, 768, and 1440 widths. Login and registration forms overflow or deform on narrow screens
    Form validation Test empty submissions, overly long input, invalid phone numbers, and duplicate submissions during concurrent clicks. Only a front-end toast appears, with no field-level validation messages
    Data decoupling Check whether product arrays are hard-coded inside components. Mock data is scattered everywhere, and real API integration requires a rewrite
    Architectural authenticity Check whether hooks, context, and state layers are shells without real content. Directories exist, but files are empty
    Asset strategy Check whether images have dimension declarations and lazy loading. Layout shifts, slower first-screen rendering
    Accessibility Check form label association, ARIA attributes for error messages, and contrast. Color blocks without text, no focus styles

    Among these dimensions, responsive behavior and data decoupling are often the most effective at revealing the upper limit of an AI coding tool.

    Form deformation on narrow screens is usually caused by fixed widths or flex items that do not wrap. The fix is to allow shrinking and constrain content width:

    1. /* Narrow-screen form container: allow shrinking, limit max width, stack fields vertically */
    2. .auth-form {
    3. display: flex;
    4. flex-direction: column;
    5. gap: 12px;
    6. width: 100%;
    7. max-width: 400px;
    8. margin-inline: auto;
    9. padding-inline: 16px;
    10. box-sizing: border-box;
    11. }
    12. .auth-form__row {
    13. display: flex;
    14. gap: 12px;
    15. min-width: 0; /* Key: allow flex items to shrink and prevent overflow */
    16. flex-wrap: wrap;
    17. }
    18. .auth-form__input {
    19. flex: 1 1 180px;
    20. min-width: 0;
    21. max-width: 100%;
    22. }
    23. /* Ensure the primary button text has sufficient contrast against the background */
    24. .btn--primary {
    25. background: var(--color-primary);
    26. color: #fff;
    27. }

    5. Data-Layer Decoupling: The Key to Long-Term Evolution

    One of the most common architectural debts in AI-generated projects is tight coupling between mock data and the view layer.

    A bad example looks like this:

    1. // Bad example: data is hard-coded inside the component, so it cannot switch to a real API
    2. function ProductList() {
    3. const list = [
    4. { id: '1', title: 'Product A', price: 9900 },
    5. { id: '2', title: 'Product B', price: 19900 },
    6. ];
    7. return /* ... */;
    8. }

    A better approach is to extract a data-access layer and let the view depend only on that interface:

    1. // src/api/catalog.ts
    2. import type { Product } from '../types/domain';
    3. export interface CatalogQuery {
    4. keyword?: string;
    5. categoryId?: string;
    6. sort?: 'new' | 'price_asc' | 'price_desc';
    7. page: number;
    8. pageSize: number;
    9. }
    10. export interface PageResult<T> {
    11. items: T[];
    12. total: number;
    13. page: number;
    14. pageSize: number;
    15. }
    16. export async function fetchProducts(
    17. q: CatalogQuery,
    18. signal?: AbortSignal,
    19. ): Promise<PageResult<Product>> {
    20. // Local mock data and the real API share the same implementation boundary.
    21. // When switching, only this layer needs to change.
    22. const res = await fetch('/api/products?' + new URLSearchParams(
    23. Object.entries(q).filter(([, v]) => v !== undefined) as string[][],
    24. ), { signal });
    25. if (!res.ok) throw new Error(`catalog fetch failed: ${res.status}`);
    26. return res.json();
    27. }

    On the view side, only three states need to be retained: loading, error, and empty state.

    1. // src/pages/ProductList.tsx (illustrative)
    2. const [state, setState] = useState<{ data?: PageResult<Product>; error?: string; loading: boolean }>({
    3. loading: true,
    4. });
    5. useEffect(() => {
    6. const ctrl = new AbortController();
    7. setState({ loading: true });
    8. fetchProducts(query, ctrl.signal)
    9. .then((data) => setState({ data, loading: false }))
    10. .catch((e: Error) => {
    11. if (e.name !== 'AbortError') setState({ error: e.message, loading: false });
    12. });
    13. return () => ctrl.abort();
    14. }, [query]);

    The direct benefit is that when a real backend is introduced, pages do not need to be rewritten. Only the data-layer implementation needs to be replaced, and the environment variables can be used to switch behavior.

    1. # .env.local
    2. VITE_API_BASE=/api # Local development uses the API mock service
    3. # VITE_API_BASE=https://your-api.example.com

    6. The Correct Way to Ask AI to Fix Problems

    It is almost inevitable that the first output will contain errors.

    A low-efficiency approach is to say, “It is broken, fix it.”

    A high-efficiency approach is to provide:

    • reproducible minimal information;
    • expected behavior;
    • acceptance criteria.

    For example:

    1. Symptom: The build fails after running the build command, with the error that module ./components/ProductCard cannot be found.
    2. Investigation: src/components/ contains a nested directory named components/ProductCard/ with the same name.
    3. Expected: A single file src/components/ProductCard.tsx exists, and routes / and /product/:id are accessible.
    4. Constraints: Do not add new dependencies and do not modify existing style variables.
    5. Acceptance: The build passes, there are no console errors, and both pages render the first screen correctly.

    At the same time, establish a hard rule:

    After every fix round, rerun the build and type checking, and regress all pages that passed in the previous round.

    Otherwise, it is easy to fall into repeated oscillation: “fixing page A breaks page B.”

    7. Integrating AI Output into an Engineering Pipeline

    AI generation is only the starting point. Whether the result can enter production depends on subsequent engineering constraints.

    1. Specification as a document
      Maintain a coding convention document in the project root directory. It should include the technology stack, directory structure, naming conventions, and prohibited items. The tool should be able to read it during every task to reduce style drift.

    2. Quality gates
      Enforce type checking and static analysis before commits. Run unit tests, component tests, and builds in the CI pipeline after commits.

    3. Dependency control
      AI coding tools tend to introduce extra dependencies. During review, confirm the necessity and maintenance status of every new dependency, and lock versions.

    4. Code review
      Apply the same review standards to AI-generated code as to human-written code. Pay special attention to authentication, amount calculation, error handling, and data validation.

    5. Test supplementation
      Let AI generate unit tests for pure logic, such as amount calculation, coupon threshold calculation, and order status transitions. These tests usually provide a much higher return on investment than page screenshot comparisons.

    8. From Prototype to Launch: What Still Needs to Be Completed

    Getting a ten-page site to run only covers the front-end presentation layer. To launch a real product, the following areas still need to be completed:

    • Authentication and sessions
      Login state should be based on credentials issued by the server. The front end should only be responsible for carrying and refreshing credentials. Do not hard-code secrets or validation logic in the browser.

    • Data persistence
      Products, orders, and coupons require a database and migration scripts. Store amounts as integer cents to avoid floating-point errors.

    • Asset delivery
      Product images should be stored in object storage, accelerated through a content delivery network, and generated in multiple sizes as needed.

    • Payment
      Integrate with a payment sandbox environment for end-to-end testing. Callbacks must implement idempotency and signature validation.

    • Observability
      Connect front-end error reporting, API latency metrics, and key funnel conversion data to logging and monitoring systems. This improves problem diagnosis. These common capabilities can be provided by cloud providers through base product categories such as object storage, content delivery network, logging service, monitoring and alerting, and container platforms. The specific choice should depend on workload and compliance requirements.

    • Compliance requirements
      User registration should include a clear privacy policy and authorization for personal information processing. Pages involving payment and orders should use transport encryption.

    9. Conclusion: Build Your Own Evaluation Baseline

    The capability differences of AI coding tools are ultimately reflected in how they make trade-offs when the context budget runs out: do they preserve architecture and contracts while compressing page details, or do they preserve visual effects while losing data decoupling?

    The former can support continuous iteration. The latter can only support a one-time demonstration.

    Three practical recommendations for teams:

    1. Build a task set
      Treat end-to-end tasks such as “building a ten-page e-commerce site” as fixed regression cases. Run them after every tool upgrade and record the results in a unified scoring table.

    2. Preserve prompt assets
      The four core assets—route table, data contract, design tokens, and prohibitions—can be reused. Turn one-off prompts into engineering assets.

    3. Keep manual acceptance gates
      Treat completeness, consistency, responsive behavior, and data decoupling as four non-negotiable baselines. Only after meeting them should efficiency improvement be discussed.

    When this process becomes stable, the value of AI tools is no longer measured by “how many lines of code were generated,” but by the efficiency of converting requirements into a maintainable codebase.