- From: Alexander Vorobyev <notifications@github.com>
- Date: Tue, 21 Oct 2025 21:46:07 -0700
- To: whatwg/url <url@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/url/issues/889@github.com>
Voral created an issue (whatwg/url#889)
### What problem are you trying to solve?
The current implementation of `URLSearchParams` has a significant flaw when working with multiple parameters of the same name. Both `set()` and `append()` methods ultimately result in data loss when the URL is processed by most backend frameworks (especially PHP, some Java servlets, and others).
**Current behavior:**
```javascript
const params = new URLSearchParams();
params.append('category', 'books');
params.append('category', 'movies');
params.append('category', 'music');
console.log(params.toString()); // "category=books&category=movies&category=music"
```
When this reaches a typical PHP backend:
```php
// $_GET['category'] contains only 'music' - data loss!
```
**The problem:**
- The API suggests support for multiple values via `append()`
- But the string representation is incompatible with how most backend systems handle repeated parameters
- This misleads developers into thinking they can safely use multiple values
- Results in silent data loss that's hard to debug
### What solutions exist today?
Currently, developers must implement manual workarounds:
```javascript
// Manual grouping
const groups = {};
['books', 'movies', 'music'].forEach(value => {
groups['category'] = groups['category'] ? groups['category'] + ',' + value : value;
});
// Then manually construct: "category=books,movies,music"
// Or use array notation manually
const params = ['books', 'movies', 'music'].map(v => `category[]=${v}`).join('&');
// "category[]=books&category[]=movies&category[]=music"
```
These solutions are:
- Error-prone and require extra code
- Inconsistent across different codebases
- Not discoverable for new developers
### How would you solve it?
Add an optional parameter to the constructor for logical grouping:
```javascript
// Current behavior (default for backward compatibility)
const params1 = new URLSearchParams();
// OR
const params2 = new URLSearchParams({ groupMultiple: false });
// New grouped behavior
const params3 = new URLSearchParams({ groupMultiple: true });
params3.append('category', 'books');
params3.append('category', 'movies');
console.log(params3.toString()); // "category=books,movies"
// Alternative: array notation
const params4 = new URLSearchParams({ groupMultiple: 'brackets' });
params4.append('category', 'books');
params4.append('category', 'movies');
console.log(params4.toString()); // "category[]=books&category[]=movies"
```
**Additional methods could include:**
```javascript
params.getMultiple('category'); // ['books', 'movies'] - returns all values
params.toString({ groupMultiple: true }); // override default for this call
```
### Anything else?
**Why this matters:**
- Prevents silent data loss in production applications
- Aligns with how form data with multiple checkboxes typically works
- Provides a migration path from current behavior
- Makes the API actually useful for real-world form handling
**Backward compatibility:**
- Default behavior remains unchanged (`groupMultiple: false`)
- New behavior is opt-in via constructor parameter
- No breaking changes for existing code
This would make `URLSearchParams` actually practical for handling form data with multiple selections, rather than being a footgun that looks like it supports multiple values but actually doesn't work with common backend systems.
--
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/url/issues/889
You are receiving this because you are subscribed to this thread.
Message ID: <whatwg/url/issues/889@github.com>
Received on Wednesday, 22 October 2025 04:46:11 UTC