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 & b throughout, 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.terms and 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).
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:escapeturns & into &, which the browser decodes back to a real & when itresolves the href, splitting the query string.
Steps to reproduce, on a clean Dawn install with the sample catalogue:
a & b-> /search?q=a+%26+b&options%5Bprefix%5D=last (3 results)Result: the URL becomes
Note the bare & mid-term:
qis nowaandbis a separate valuelessparameter. 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:
a & bthroughout, so the UI asserts a termthe result set does not reflect. There is no error state; the shopper simply
gets the wrong products under a correct-looking query.
search.termsand the result set disagree, and what thebox 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:
returning the same 3 results as step 1.
Version information (Dawn, browsers and operating systems)
Possible solution
url_encodealone is not sufficient, becausesearch.termsis returned alreadyHTML-escaped and Liquid's
escapeis escape-once. Evidence:{{ search.terms | size }}returns 16 for a typedtweed & wool(12 characters),and the term
a&b<c>d"e'fcomes back asa&b<c>d"e'f. Sourl_encodeon its own yieldsa%26amp%3Bb...- the entity encoded rather thanthe 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:
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 avoidshand-built URLs everywhere else by using the platform-generated
value.url_to_remove/filter.url_to_remove; aurl_to_removeequivalent 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_urlfeeds clear-all in fiveplaces, 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).