# Progress indicator visible on multi-step checkout

- **Pattern:** `ab-001099` (`ecommerce-cart-ux.checkout-flow.progress-indicator`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001099
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001099)

## Why it matters

A multi-step checkout with no progress indicator leaves shoppers wondering whether they're two forms away from paying or six. Uncertainty drives abandonment — Nielsen Norman research shows users tolerate longer flows when they can see the end. Missing progress cues also break screen-reader navigation, since assistive tech users rely on landmark regions and aria-current to orient. The progress indicator is also the primary anchor for back-navigation jumps, so its absence forces linear-only movement.

## Severity rationale

High because uncertainty about remaining steps measurably increases mid-checkout abandonment on multi-page flows.

## Remediation

Render a stepper component in `src/app/checkout/layout.tsx` so it appears on every checkout page. Show current step number, total count, and labeled steps. Wire `aria-current="step"` on the active step for assistive tech. Do not ship a bare progress bar with no labels — the contract rejects context-free indicators.

```tsx
<nav aria-label="Checkout progress">
  <p>Step {currentStep} of {totalSteps}</p>
  {steps.map((label, i) => <div aria-current={i === currentStep - 1 ? 'step' : undefined}>{label}</div>)}
</nav>
```

## Detection

- **ID:** `progress-indicator`
- **Severity:** `high`
- **What to look for:** Count the checkout steps (from step-count check above). If 2 or more steps exist, search for a progress indicator component — numbered stepper, progress bar, breadcrumb, or "Step X of Y" text. Look in checkout layout files (e.g., `src/app/checkout/layout.tsx`) and shared checkout components. Quote the indicator element or component name if found.
- **Pass criteria:** Multi-step checkout (2+ steps) displays a visible progress indicator that shows at minimum the current step number and total step count (e.g., "Step 2 of 4") or equivalent visual (progress bar with labeled steps). The indicator must render on every checkout step, not just the first. Report even on pass: "Progress indicator found in [component/file], showing X-step progress on all Y checkout pages."
- **Fail criteria:** Multi-step checkout has no progress indicator, or the indicator appears on fewer than 100% of checkout steps, or the indicator shows step names but not how many remain.
- **Do NOT pass when:** A progress bar exists but shows no step labels or numbers — a generic bar with no context does not count as a progress indicator.
- **Skip (N/A) when:** Checkout is single-step or single-page (no progress indicator needed for 1-step flows).
- **Detail on fail:** Example: `"3-step checkout across src/app/checkout/[step]/ pages has no progress indicator component. 0 of 3 checkout pages show step position. User doesn't know how many steps remain."`
- **Cross-reference:** For mobile rendering of progress indicators, see the mobile-viewport check in Order Summary & Confirmation. For accessibility of step indicators, the Accessibility Fundamentals audit covers ARIA roles and navigation landmarks.
- **Remediation:** Add a progress component in your checkout layout at `src/app/checkout/layout.tsx` or `src/components/CheckoutProgress.tsx`:

  ```tsx
  // src/components/CheckoutProgress.tsx
  function CheckoutProgress({ currentStep, totalSteps, steps }) {
    return (
      <div className="progress" role="navigation" aria-label="Checkout progress">
        <p>Step {currentStep} of {totalSteps}</p>
        <div className="progress-bar">
          {steps.map((label, idx) => (
            <div
              key={idx}
              className={`step ${idx < currentStep ? 'done' : idx === currentStep - 1 ? 'active' : ''}`}
              aria-current={idx === currentStep - 1 ? 'step' : undefined}
            >
              {label}
            </div>
          ))}
        </div>
      </div>
    )
  }
  ```

Taxons: user-experience

HTML version: https://auditbuffet.com/patterns/ab-001099
