URLSearchParams Polyfill
This library provides a comprehensive polyfill for the native JavaScript `URLSearchParams` interface, allowing web developers to utilize its functionality in environments that lack full support, such as older browsers (e.g., IE8+) or specific Node.js versions. The current stable version is 8.2.5. The project appears to have a moderate release cadence, addressing bugs and adding features as needed, with major versions often introducing specific bug fixes or minor behavioral changes rather than massive overhauls. Key differentiators include its broad browser compatibility (down to IE8), full implementation of the MDN specification, and detection of existing `URLSearchParams` implementations to extend them rather than completely overwrite. It works seamlessly in both browser and Node.js environments, ensuring consistent behavior across different JavaScript runtimes.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'hasOwnProperty')
cause Attempting to use `Object.prototype` properties like `hasOwnProperty`, `toString`, etc., as search parameter names in older versions of the polyfill.fixUpgrade `url-search-params-polyfill` to version 8.0.0 or higher. This version specifically addresses and fixes the bug allowing these property names to be used. -
URIError: URI malformed
cause Parsing a query string that contains un-decodable `%` escape sequences with versions prior to 6.0.0.fixUpdate `url-search-params-polyfill` to version 6.0.0 or newer. This version includes a fix to handle such malformed URI components gracefully without throwing an error. -
Request body for fetch API is not correctly interpreted as form data.
cause Using `URLSearchParams` as a `fetch` request body in browsers that support `fetch` but lack native `URLSearchParams`, without manually setting the `Content-Type` header.fixWhen creating a `fetch` request with a `URLSearchParams` body, explicitly set the `Content-Type` header to `'application/x-www-form-urlencoded; charset=UTF-8'`.
Warnings
- breaking Version 8.0.0 fixed a serious bug where `Object.prototype` properties (e.g., `hasOwnProperty`) could not be used as search parameter names and would cause an error. If your application inadvertently or intentionally used such names, this update changes behavior to correctly handle them.
- breaking Version 6.0.0 changed the behavior of decoding query strings containing special characters. Previously, if a query string had an un-decodable `%` character, it would fail to parse and throw an error. This version fixes the issue, leading to different parsing results for malformed URIs.
- breaking Version 4.0.0 updated the prototypes of `keys()` and `values()` methods. They no longer wrap individual elements in their own arrays. This is a breaking change if your iteration logic or data processing relied on `keys()` or `values()` returning `[element]` instead of `element`.
- gotcha When using `URLSearchParams` objects with the `fetch` API in browsers that support `fetch` but lack native `URLSearchParams` support (e.g., Edge 14-16, Chrome 40-48), the `Content-Type: application/x-www-form-urlencoded; charset=UTF-8` header is not automatically added. This can lead to incorrect request bodies.
- gotcha React Native has a native `URLSearchParams` implementation that is a no-op, meaning it exists but performs no actions. Version 8.1.0 changed how the polyfill detects and handles existing `URLSearchParams` support, which might alter behavior in React Native environments compared to prior versions.
Install
-
npm install url-search-params-polyfill -
yarn add url-search-params-polyfill -
pnpm add url-search-params-polyfill
Imports
- Polyfill
import { URLSearchParams } from 'url-search-params-polyfill';import 'url-search-params-polyfill';
- Polyfill (CommonJS)
const URLSearchParams = require('url-search-params-polyfill');require('url-search-params-polyfill'); - URLSearchParams Constructor
const params = new Polyfill.URLSearchParams();
const params = new URLSearchParams();
Quickstart
import 'url-search-params-polyfill'; // Ensure the polyfill is active
// Instantiate URLSearchParams from various sources
const searchFromString = new URLSearchParams("id=101&from=dashboard&tags=alpha&tags=beta");
console.log('From string:', searchFromString.toString()); // id=101&from=dashboard&tags=alpha&tags=beta
const searchFromObject = new URLSearchParams({ product: 'widget', category: 'electronics' });
searchFromObject.append('color', 'red');
searchFromObject.set('category', 'home-goods');
console.log('From object:', searchFromObject.toString()); // product=widget&category=home-goods&color=red
const queryParams = new URLSearchParams();
queryParams.append("user", "john.doe");
queryParams.append("role", "admin");
queryParams.set("status", "active");
queryParams.append("tags", "new");
queryParams.append("tags", "featured");
console.log("All 'tags' values:", queryParams.getAll("tags")); // ["new", "featured"]
console.log("Has 'user'?", queryParams.has("user")); // true
console.log("Query string:", queryParams.toString()); // user=john.doe&role=admin&status=active&tags=new&tags=featured
queryParams.delete("role");
queryParams.sort();
console.log("Sorted query string after deleting role:", queryParams.toString()); // status=active&tags=featured&tags=new&user=john.doe
for (const [key, value] of queryParams) {
console.log(`Key: ${key}, Value: ${value}`);
}