All 22 checks with why-it-matters prose, severity, and cross-references to related audits.
Directory users arrive with intent — they want to find a specific listing, not browse aimlessly. When search is hidden below the fold on mobile, buried in a hamburger menu, or missing from category pages entirely, users bounce before they engage. Mobile traffic typically drives 60-70% of directory sessions, and forcing a scroll-then-tap-menu-then-tap-search sequence collapses conversion. This is a core user-experience failure mode that directly reduces listing views, claim rates, and advertising revenue.
Why this severity: Critical because the search bar is the primary entry point to the directory's value and hiding it on mobile cuts conversion at the top of the funnel.
directory-search-discovery.search-input.search-present-mobileSee full patternAutocomplete latency above 300ms breaks the perceptual contract users have with search — they stop trusting the suggestions and abandon the feature entirely. ISO 25010:2011 performance-efficiency frames this as a functional responsiveness requirement, not a nice-to-have. Directories that serve irrelevant or hardcoded suggestions compound the damage: users waste time selecting a suggestion that returns no matching listings, eroding confidence in the product. On mobile networks, where the autocomplete round-trip competes with elevated latency, a bloated debounce delay also hammers your backend with redundant queries on every keystroke, driving up infrastructure cost.
Why this severity: High because autocomplete latency above 300ms measurably degrades engagement and causes users to abandon search before submitting a query.
directory-search-discovery.search-input.autocomplete-speedSee full patternUnescaped special characters in search queries are a direct path to SQL injection (CWE-89) and OWASP A03:2021 Injection — apostrophes, quotes, and backslashes passed raw into a query string can terminate the intended SQL clause and execute attacker-controlled statements. Beyond active exploitation, the same bug silently breaks legitimate searches: `John's Café`, `Fish & Chips`, and `Rock (n roll)` are common real-world listing names that will surface 500 errors if input validation is absent. Every error response leaks backend implementation details and destroys user trust at the exact moment they're trying to find something.
Why this severity: High because unescaped input enables SQL injection (CWE-89, OWASP A03) and crashes the search experience for ordinary user input containing apostrophes or special characters.
directory-search-discovery.search-input.special-chars-handlingSee full patternWhen a user submits `Italian restaurants` and the results page renders without echoing that query anywhere on-screen, the user has no confirmation that their search was understood. They cannot tell whether the page is filtered, whether typos were preserved, or whether they landed on the wrong route. This is a fundamental user-experience failure: the results page must close the feedback loop by reflecting the exact string the user typed, otherwise trust in the search breaks down and the user re-enters the query or bounces.
Why this severity: High because users lose orientation and re-query repeatedly, inflating bounce rates and server load without compromising security or data integrity.
directory-search-discovery.search-input.query-reflectionSee full patternA directory that full-reloads on every filter click feels broken on any connection slower than corporate fiber. Each reload throws away scroll position, re-runs layout shift, refetches unchanged header and footer chunks, and adds 200-800ms of perceived latency per filter adjustment. Users who would have iterated through three or four filter combinations abandon after one. Modern directories live or die on the speed at which users can refine results — a full-page refresh loop is the single largest UX regression in this category.
Why this severity: Critical because filter interactions are the core refinement loop and page reloads collapse iteration speed below the threshold where users keep exploring.
directory-search-discovery.facets-filters.filter-no-reloadSee full patternWhen active filters have no visible representation, users forget which constraints are in play. They see 3 results, assume the directory is empty, and leave — never realizing a price cap or category filter is silently excluding hundreds of listings. When filters lack individual remove buttons, the only escape is a full reset, which destroys the user's other selections and forces them to rebuild. Both failure modes compound: invisible filters produce abandonment, and all-or-nothing removal punishes exploration.
Why this severity: Critical because invisible or non-removable filters trap users in unexpected result sets and erase confidence in the filtering system.
directory-search-discovery.facets-filters.active-filters-visibleSee full patternFilter counts that show global totals instead of intersected totals (ISO 25010:2011 functional-suitability) actively mislead users. A user filtering by "Restaurants" who then sees "Rating: 4+ stars (847)" expects that number to reflect restaurants with high ratings — if it still reflects all 847 rated listings in the directory, they'll apply the filter expecting hundreds of results and land on a handful. This mismatch generates rage-clicks, support tickets, and abandoned sessions. The data contract between UI label and backend query must be exact: a count badge is a promise.
Why this severity: High because stale global counts misrepresent the result set, causing users to make filter decisions based on incorrect data and destroying trust in the search experience.
directory-search-discovery.facets-filters.filter-counts-dynamicSee full patternUsers accumulate filters exploratively — they click a category, a price range, a rating threshold, then realize they want to start over. Without a clear-all control, they must find and click the remove button on each chip one at a time, or figure out that clicking the filter again toggles it off. Both paths take 4-8 seconds of friction at the moment the user most wants to restart their exploration. A single `Clear all` button resolves this to one click and signals that the interface respects the user's time.
Why this severity: High because filter reset is a frequent action and per-filter teardown compounds friction at the exact moment users want to pivot their search.
directory-search-discovery.facets-filters.clear-all-buttonSee full patternRange filters rendered as freeform text inputs (`<input type="text">`) violate WCAG 2.2 SC 1.3.5 (Identify Input Purpose) and SC 4.1.2 (Name, Role, Value) — screen readers cannot convey the expected value type, and users relying on step controls or browser autofill get nothing. Beyond accessibility, freeform text introduces validation surface area: users enter "10-50", "$10 to $50", or "ten dollars" and the backend must parse all variants or return unexpected results. Semantic number or range inputs constrain input to a machine-readable format without custom parsing.
Why this severity: Low because the failure degrades usability and assistive technology access without directly exposing data or enabling exploitation.
directory-search-discovery.facets-filters.range-filter-a11ySee full patternBoolean filters rendered as clickable divs or unsemantic buttons fail WCAG 2.2 SC 4.1.2 (Name, Role, Value) and SC 1.3.1 (Info and Relationships) — a screen reader user lands on a div that says "Has WiFi" with no indication it is togglable, interactable, or currently active. This eliminates the filtering experience entirely for keyboard-only and assistive technology users. Beyond accessibility, div-based toggles break browser default behaviors: they don't receive focus in the correct tab order, don't respond to Space or Enter as checkboxes do, and don't participate in form submission.
Why this severity: Low because the failure blocks screen reader and keyboard users from accessing filters without creating a security or data integrity risk.
directory-search-discovery.facets-filters.boolean-a11ySee full patternA persistent sidebar that consumes 40% of a 320px mobile viewport leaves roughly 190px for result cards — too narrow to show an image, name, category, and rating without wrapping badly. Users end up scrolling a cramped single-column list through a filter rail they aren't actively using, and the directory feels like a desktop site squeezed onto a phone. A drawer or modal pattern reclaims the full viewport for results and gates filter interaction behind an explicit tap.
Why this severity: Low because the result set is still reachable, but cramped layouts measurably reduce card scanability and mobile engagement depth.
directory-search-discovery.facets-filters.mobile-filter-uxSee full patternNon-deterministic or unlabeled sort order is a functional suitability failure under ISO 25010:2011 — users cannot form a mental model of what they're looking at. A directory that silently returns results in insertion order, or randomizes on each page load, makes it impossible to compare two sessions or share a result. In practice, unnamed sort states generate support requests ("why did the top result change?") and break bookmark workflows entirely. The absence of a sort label also means users cannot tell whether they're browsing by relevance, recency, or rating — so they can't trust any individual result's position.
Why this severity: High because a non-deterministic or unlabeled sort order destroys result reproducibility and prevents users from making informed decisions about result ranking.
directory-search-discovery.results-sorting.default-sort-labeledSee full patternWhen changing sort order wipes active filters, the user watches their carefully refined query collapse back to the unfiltered state in one click. They rebuild the filters, sort again, and it collapses again — or they give up. This is a state-management bug that reads to the user as the directory being fundamentally unreliable. Sort is a refinement of the existing result set, not a reset, and confusing the two guarantees the user never trusts the interface enough to commit to a listing.
Why this severity: High because silent filter loss destroys user work and signals the interface cannot be trusted to preserve intent across interactions.
directory-search-discovery.results-sorting.sort-preserves-stateSee full patternResult cards are the scanning surface where users decide which listing to click into. A card showing only a name and image forces users to open every result to compare them, destroying the point of a listing grid. A card with name, category, image, and at least one distinguishing signal (rating, distance, price, hours) lets users triage 20+ listings in seconds. This is a content-integrity and user-experience failure simultaneously: thin cards bury the directory's data value and tank click-through to detail pages.
Why this severity: High because thin cards force open-every-result scanning, which collapses engagement depth and inflates bounce from detail pages.
directory-search-discovery.results-sorting.card-contentSee full patternWhen search state lives only in client memory, the back button becomes useless, sharing a result page over Slack or email delivers the unfiltered homepage, and refreshing the tab wipes every refinement. Users expect URLs to be durable addresses — breaking that contract means every deep link from Google, Reddit, or a friend lands on the wrong state. URL-synced state is also the only reliable way to give users back/forward history through their filter exploration, which doubles as an undo stack.
Why this severity: Critical because URL-less state breaks sharability, bookmarks, back/forward navigation, and SEO indexing of filtered views.
directory-search-discovery.pagination-url.url-state-syncSee full patternSearch results that can't be shared via URL are functionally private — users cannot bookmark a filtered view, send a result set to a colleague, or return to the same context after closing a tab. This violates ISO 25010:2011 functional-suitability and is a first-order UX failure for any directory product where sharing and referral are core growth mechanics. Non-shareable URLs also break SEO: search engines cannot index filtered result pages, eliminating long-tail keyword traffic for category, location, and attribute combinations that represent the directory's core value.
Why this severity: High because non-shareable URLs eliminate bookmark, referral, and SEO surface area — all of which are foundational to a directory's discovery and growth model.
directory-search-discovery.pagination-url.shareable-urlsSee full patternPagination without visible progress context — no current page number, no total page count — leaves users navigating blind. Under ISO 25010:2011 reliability, an application that crashes or returns an unhandled error on an out-of-range page number has a reliability defect. The failure surface is trivially reachable: any user who manually edits `?page=999` in a URL, or who follows a stale link to a page that no longer exists, hits the boundary. A crash response (500, unhandled exception, blank page) signals to search engine crawlers and users alike that the application is fragile.
Why this severity: High because missing page context disorients users and out-of-bounds page requests that crash the application create a reliability defect visible to both users and crawlers.
directory-search-discovery.pagination-url.pagination-uxSee full patternA blank results grid after a zero-match search reads as a broken page. Users do not infer `your filters are too narrow` — they infer `this site is down` or `this directory doesn't have what I need` and bounce. A deliberate empty state with a message naming what was searched, an explanation of why zero matched, and clear next-action buttons (clear filters, view all, browse categories) recovers the session and keeps the user inside the funnel instead of back in Google typing a competitor's name.
Why this severity: High because unhandled zero-result pages read as broken and cause immediate bounces that lose the session entirely.
directory-search-discovery.pagination-url.empty-stateSee full patternA blank page or raw stack trace on a search error tells users nothing actionable and exposes internal implementation details — error messages containing `TypeError: Cannot read property of undefined` or Prisma stack traces reveal your ORM, schema, and query structure. Under ISO 25010:2011 reliability, an application that silently drops into an empty state on network failure or backend error leaves users unable to distinguish "no results" from "broken search" — and they'll assume the latter, blame the product, and leave.
Why this severity: Medium because the failure degrades user trust and leaks implementation details without constituting a direct data breach or service outage.
directory-search-discovery.pagination-url.error-handlingSee full patternA search input without an associated label fails WCAG 2.2 SC 4.1.2 (Name, Role, Value) — screen readers announce the field as "edit text" with no context, making it unusable for blind users. Autocomplete dropdowns that don't use `aria-live` or `role="listbox"` are invisible to assistive technology: suggestions appear visually but are never announced, so keyboard and screen reader users cannot benefit from them. WCAG 2.2 SC 4.1.3 (Status Messages) further requires that dynamic content changes like suggestion updates be communicated without requiring focus movement.
Why this severity: Medium because the failure eliminates search usability for screen reader users while stopping short of a critical data or security exposure.
directory-search-discovery.pagination-url.search-a11ySee full patternA sort control built from unsemantic divs or buttons fails WCAG 2.2 SC 4.1.2 (Name, Role, Value) and SC 2.1.1 (Keyboard) — keyboard users cannot tab to the control, screen readers cannot identify it as an interactive dropdown, and arrow-key navigation expected of a listbox never fires. Sorting is a primary navigation mechanism in any results page; locking it behind mouse-only interaction excludes a non-trivial portion of users and makes the directory non-compliant in any context where WCAG conformance is required (government contracts, enterprise procurement, ADA-adjacent legal exposure).
Why this severity: Low because the failure blocks keyboard and screen reader access to sorting without exposing data or creating a security risk.
directory-search-discovery.pagination-url.sort-a11ySee full patternA listing grid that doesn't reflow at 320px produces horizontal scroll, clipped card content, and text that runs off the edge of the phone. At 768px, oversized cards wrap into awkward half-widths. Each broken breakpoint silently excludes a slice of the audience — mobile users on cheap Android devices, tablet users in landscape, users at zoom 150% on a 1280px laptop. Responsive grid behavior is table-stakes for any directory serving traffic beyond a narrow desktop-only demographic.
Why this severity: Low because content remains accessible but broken breakpoints compound with card content issues to degrade mobile and tablet experience.
directory-search-discovery.pagination-url.responsive-gridSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Search & Discovery UX Audit