Clear all discards the search term when the term contains an ampersand
Nobody has claimed this yet.
- Dominant language
- Liquid
- Stars
- 3.1k
- Forks
- 4.5k
- PR merge metrics
- No merged PRs in 30d
Description
Describe the current behavior
On a search results page, "Remove all" / "Clear all" silently discards the search
term when the term contains an ampersand (or <, >, " or '), returning the entire
catalogue instead of the filtered search.
snippets/facets.liquid:26 builds the clear-all URL from the search term with
escape, an HTML escaper, rather than a URL encoder:
assign terms = results.terms | escape
assign results_url = '?q=' | append: terms | append: '&options%5Bprefix%5D=last&sort_by=' | append: sort_by
escape turns & into &, which the browser decodes back to a real & when it
resolves the href, splitting the query string.
Steps to reproduce, on a clean Dawn install with the sample catalogue:
- Search for
a & b-> /search?q=a+%26+b&options%5Bprefix%5D=last (3 results) - Apply any filter, e.g. Availability: In stock (2 results)
- Click "Remove all"
Result: the URL becomes
?q=a%20&%20b&options%5Bprefix%5D=last&sort_by=relevance
Note the bare & mid-term: q is now a and b is a separate valueless
parameter. The page returns 45 results - the whole catalogue - and the filter row
switches to catalogue-wide facets (Region, Colour, Volume) instead of the
search's own.
Two details worth flagging:
- The search input still displays
a & bthroughout, so the UI asserts a term
the result set does not reflect. There is no error state; the shopper simply
gets the wrong products under a correct-looking query. - On the broken URL,
search.termsand the result set disagree, and what the
box renders varies by theme. The reliable test is the result count, not the
displayed term.
Describe the expected behavior
"Remove all" clears the filters and preserves the search term:
?q=a+%26+b&options%5Bprefix%5D=last&sort_by=relevance
returning the same 3 results as step 1.
Version information (Dawn, browsers and operating systems)
- Dawn Version: 16.0.0
- Edge Version: 152.0.4191.66 (Official build) (64-bit)
- Windows 11
Possible solution
url_encode alone is not sufficient, because search.terms is returned already
HTML-escaped and Liquid's escape is escape-once. Evidence:
{{ search.terms | size }} returns 16 for a typed tweed & wool (12 characters),
and the term a&b<c>d"e'f comes back as a&b<c>d"e'f. So
url_encode on its own yields a%26amp%3Bb... - the entity encoded rather than
the character - and repeated clicks compound it (& -> &amp;).
Unwinding the entities before encoding, with the ampersand last so earlier
replacements cannot be re-read, does round-trip correctly:
assign terms = results.terms | replace: '<', '<' | replace: '>', '>' | replace: '"', '"' | replace: ''', "'" | replace: '&', '&' | url_encode
That is a workaround rather than a fix. The underlying issue is that the clear-all
URL has to be rebuilt by hand at all: Liquid exposes no request query string, and
a search has no equivalent of a collection's results.url. Horizon already avoids
hand-built URLs everywhere else by using the platform-generated
value.url_to_remove / filter.url_to_remove; a url_to_remove equivalent for
"clear everything", or an exposed search URL, would remove the need for any
escaping logic here.
Additional context/screenshots
The same construction is present verbatim in Horizon
(blocks/filters.liquid:59-63), where results_url feeds clear-all in five
places, so the fix likely wants applying in both themes. Horizon has issues
disabled, hence reporting here.
Related but distinct: #2198 covered the drawer 'Clear' action clearing all
filters rather than one group, and was closed in January 2023. This is the
query-string encoding of the clear-all URL, not the scope of the action.
Reproduced on Dawn 16.0.0 (current release, v16.0.0 / theme_version 16.0.0).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with snippets/facets.liquid:26 and compare the matching construction in Horizon at blocks/filters.liquid:59-63. Reproduce the clear-all flow with a search term containing an ampersand and verify the generated URL preserves the term. Done means clearing filters keeps the same search results in both themes without corrupting the query string.
Written by the indexing model from the issue text.
Assessment
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100