A filter page can legitimately contain the same query key more than once. A reader selecting both ceramics and textiles might produce ?topic=ceramics&topic=textiles. The choice between append() and set() determines whether both selections survive.
According to the MDN append reference, appending adds another value for the key. The set reference explains that setting a value replaces the existing values for that key. If it was absent, the key is created.
Try the two operations on the same starting point
const filters = new URLSearchParams('topic=ceramics');
filters.append('topic', 'textiles');
console.log(filters.getAll('topic'));
// ['ceramics', 'textiles']
filters.set('topic', 'glass');
console.log(filters.getAll('topic'));
// ['glass']
The example models a multi-select control followed by a deliberate replacement. Calling set() for each checked option would leave only the last one. Calling append() every time the same option is toggled on could instead accumulate unwanted repeated values unless the rest of the control manages them.
Test the receiving end too
A correctly constructed browser query is only half the interface. The server or framework may expose repeated keys as a list, return one value, or require another documented convention. Write a small integration test that confirms the intended selections reach the application.
Include an empty selection, one value, two values and a value containing spaces or punctuation. Pass the unencoded value to the API rather than manually adding percent escapes beforehand. Otherwise the URL may represent the escape characters instead of the original text.
Use getAll() when inspecting repeated keys; a single-value read can hide the fact that more than one exists. Keep the query format documented next to the filter code so the frontend and backend agree.
The method names describe two different intentions: adding another value and replacing the selection. Choosing deliberately makes the URL easier to reason about and the interface less likely to lose a user’s filters.

