usability.cat
Issue Wiki

Missing Back Navigation

Your visitors have no clear way back. It's a one-way street with no U-turn — and the browser back button isn't always reliable.

What is this?

You are driving down a one-way street. You realize you have gone too far. You need to turn around, but there are no U-turns, no side streets, and no signs pointing back. Your only option is to keep going and hope for the best. That is what your website feels like when there is no clear way to go back. Yes, browsers have a back button — but that is not always enough. Single-page apps can break it, opened links can lose it, and many mobile users do not even think to use it. Your site needs its own "way back" that visitors can see and trust.

Why it matters

  • For your visitors: When someone clicks into a detail page or a multi-step form and cannot find their way back, panic sets in. Where was I? How do I return? The feeling of being lost in a website is like being lost in a building — except on a website, people just close the tab.
  • For your business: Lost visitors are lost customers. If someone is three steps into checkout and cannot go back to fix their shipping address, they abandon the cart entirely. Multi-step forms without back buttons have significantly higher abandonment rates. And when the browser back button breaks in a single-page app, users land somewhere completely unexpected.
  • The standard: WCAG 2.4.5 emphasizes that users should have multiple ways to navigate, including the ability to return to previous content. Breadcrumbs (covered in a separate page) are one way. Explicit back links or buttons are another. The key principle is that users should never feel trapped or unable to reverse a navigation action.
Clear back navigation
<!-- Detail page with visible back link -->
<main>
  <a href="/products" class="back-link">
    &larr; Back to Products
  </a>
  <h1>Product Detail</h1>
  <p>Product information...</p>
</main>

<!-- Multi-step form with back button -->
<form>
  <h2>Step 2 of 3: Shipping</h2>
  <fieldset>...</fieldset>
  <div class="form-actions">
    <button type="button" onclick="goBack()">
      Back
    </button>
    <button type="submit">Continue</button>
  </div>
</form>
No way back
<!-- Detail page with no escape route -->
<main>
  <h1>Product Detail</h1>
  <p>Product information...</p>
  <!-- How do I get back to the product list? -->
  <!-- Guess I'll try the browser back button and pray. -->
</main>

<!-- Multi-step form, forward only -->
<form>
  <h2>Step 2 of 3: Shipping</h2>
  <fieldset>...</fieldset>
  <button type="submit">Continue</button>
  <!-- Can't go back. Hope you typed everything right. -->
</form>

How to fix it

React / Next.js

For detail pages: Add a back link that points to the parent listing page. Do not rely on router.back() alone — it breaks when users land directly on the page from an external link.

// src/components/back-link.tsx
import Link from "next/link";
import { ArrowLeft } from "lucide-react";

interface BackLinkProps {
  href: string;
  label: string;
}

export function BackLink({ href, label }: BackLinkProps) {
  return (
    <Link
      href={href}
      className="mb-6 inline-flex items-center gap-2 text-sm text-gray-500 hover:text-gray-900 dark:hover:text-white"
    >
      <ArrowLeft className="h-4 w-4" />
      {label}
    </Link>
  );
}
// src/app/products/[id]/page.tsx
import { BackLink } from "@/components/back-link";

export default function ProductPage() {
  return (
    <main>
      <BackLink href="/products" label="Back to Products" />
      <h1>Product Name</h1>
    </main>
  );
}

For multi-step forms: Add an explicit back button that preserves state. The key is type="button" (not submit) so clicking Back does not submit the form.

<div className="mt-6 flex gap-3">
  {step > 1 && (
    <button
      type="button"
      onClick={() => setStep(step - 1)}
      className="rounded border px-4 py-2 text-sm"
    >
      Back
    </button>
  )}
  <button
    type="button"
    onClick={() => setStep(step + 1)}
    className="rounded bg-amber-500 px-4 py-2 text-sm font-semibold text-black"
  >
    {step < totalSteps ? "Continue" : "Submit"}
  </button>
</div>

Plain HTML

<!-- Back link on detail pages -->
<a
  href="/products"
  style="display: inline-flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem; color: #6b7280; text-decoration: none;"
>
  &larr; Back to Products
</a>

<!-- Multi-step form with back button -->
<form>
  <h2>Step 2 of 3</h2>
  <fieldset>
    <!-- form fields -->
  </fieldset>
  <div style="display: flex; gap: 0.75rem; margin-top: 1.5rem;">
    <button type="button" onclick="history.back()">Back</button>
    <button type="submit">Continue</button>
  </div>
</form>

The rules: every detail page needs a back link to its parent page (not history.back(), which is unreliable). Every multi-step process needs a back button. Users should never feel like closing the browser is the only exit.

Medium impactnavigation~1 paw

A cat always has an exit strategy. Your visitors are less graceful — they need yours to be obvious.

How the cat scores this

The scanner checks several things. On detail pages (identified by URL patterns like /item/123 or pages with a single content entity), it looks for back links pointing to a parent route. On multi-step flows (forms with step indicators or progress bars), it checks for back/previous buttons on steps after the first. It also verifies that modals and overlays have close mechanisms. Pages where the only way back is the browser back button get flagged, because the scanner knows that is not reliable in single-page app contexts.

Further reading

On this page