What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Build each search URL with the browser’s URL and URLSearchParams APIs, then compare both the parsed parameter values and the serialized URL in every browser you support. Do not treat a difference such as %20 versus + as a failure unless your application or server requires one exact spelling: those encodings can represent the same space in a query.
What to compare in a search URL test
A URL query is structured data, not just a string to split on punctuation. The WHATWG URL Standard defines URL parsing and serialization, including form-style query encoding. A useful test records two separate results:
As an Amazon Associate I earn from qualifying purchases.
- Meaning: the value returned by
searchParams.get()for each parameter. - Spelling: the serialized URL or raw query string, if your application contract requires a particular representation.
For example, URL.search may show a space as %20, while serializing through URLSearchParams uses +. Updating searchParams can therefore change the visible URL even though the parsed parameter value is still equivalent. MDN documents this behavior for URL.search.
Build a repeatable cross-browser test
- Define the contract. Record the expected parameter name and value. Decide whether you care about the decoded value, the exact query string, or both. If the receiving server distinguishes
%20from+, make that requirement explicit. - Construct with the URL API. Set query values through
searchParams, rather than concatenating special-character-bearing text into a URL. - Run the same cases in each target browser. Record the browser name and version, operating system, input, serialized URL, parsed value, and pass/fail result.
- Compare decoded meaning first. Assert exact serialization only where a documented application or server requirement calls for it.
- Investigate standards discrepancies separately. The URL Standard points to the URL web-platform-tests suite as a conformance reference; a difference from your application’s desired wire format is not by itself proof of a browser bug.
A small browser-console test
Paste this in each browser’s developer console. It constructs a URL, prints its serialized form and parsed value, then checks that the parsed value matches the original input.
#1 Best Overall
const base = "https://example.com/search";
const cases = [
"ordinary text",
"two words",
"literal + plus",
"100% complete",
"a&b=c",
"what? now#fragment",
"café 東京"
];
for (const input of cases) {
const url = new URL(base);
url.searchParams.set("q", input);
const parsed = url.searchParams.get("q");
console.log({
input,
serialized: url.href,
rawQuery: url.search,
parsed,
passed: parsed === input
});
}
Replace the example base URL with your application’s search endpoint and, if needed, add more parameters using url.searchParams.set(name, value). Keep the input cases identical across runs. In a JavaScript string, & in the code above is a literal ampersand character.
Boundary cases to include
- Spaces, including leading or trailing spaces if your application permits them.
- A literal plus sign, which must not be confused with a space when decoded by the receiving application.
- Percent signs and strings that resemble percent escapes, such as
%2F. - Ampersands and equals signs, which otherwise delimit parameters and values.
- Question marks and hash characters inside a value; an unencoded hash starts a URL fragment rather than remaining part of the query.
- Non-ASCII text, such as accented Latin characters and CJK text.
- Multiple parameters, including repeated parameter names, if your endpoint supports them.
Read the results without mistaking encoding for a bug
Check that the parsed value preserves the intended characters after construction. For example, a literal plus in the input should remain a plus when read back, rather than being interpreted as a space. Then inspect the serialized query. A space represented as + or %20 can have the same meaning in the relevant query-processing context; the receiving application’s behavior determines whether the representations are interchangeable for your use case.
Rank #2
Use separate assertions for value and spelling. A value assertion might be parsed === input. An exact-string assertion should be added only if the endpoint, signature scheme, cache key, or other integration explicitly requires a particular serialized form. Server interpretation is application-specific, so include an integration check against the actual endpoint when that is what matters.
Recommended Free Tools
Record a useful browser comparison
For each run, save a compact record with these fields:
Rank #3
- Browser and version, plus operating system.
- Input text and parameter name.
- Serialized URL or raw query string.
- Value returned by
searchParams.get()(and, where relevant, values returned bygetAll()). - Whether decoded meaning matched, whether required spelling matched, and the endpoint’s observed behavior.
This procedure produces a reproducible comparison, but standards documentation alone does not establish pass/fail results for current named browser versions. Populate the matrix by running your own supported browser versions; do not infer a current compatibility result from the standard or from an older compatibility-history note.
Troubleshoot common failures
The value is cut off at an ampersand or equals sign
& separates query parameters and = separates a name from its value in a query string. Set the whole value with searchParams.set(); do not assemble the query by string concatenation.
A plus sign comes back as a space
Check how the receiving application decodes the query and whether the plus was encoded as data. Compare the browser’s parsed value with the server’s parsed value. If the server has a specific wire-format requirement, test that requirement directly rather than assuming every query decoder behaves identically.
The URL text changed after updating parameters
That may be normal serialization. Compare parsed values before declaring failure: URL.search and URLSearchParams can serialize spaces differently, and changing searchParams can rewrite the URL text.
Best Value
Text after a hash is missing from the request
A hash begins the fragment portion of a URL; fragments are not part of the query sent to a server. Set the value through searchParams so the hash character is encoded as data, then verify both the serialized URL and parsed value.
Different browsers appear to disagree
First compare the same input, base URL, and code path, then compare parsed values separately from serialization. Record exact browser versions and operating systems. If a standards-level discrepancy remains, consult the URL web-platform-tests suite; if only your backend differs, investigate its query parser and contract.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
For a visual check of a search-results page or its rendered state, ScreenshotNeo can capture a URL with one request. This does not replace the parsed-value assertions above or establish how a browser serialized a query: use the browser test for that. ScreenshotNeo is a website screenshot API and MCP server; its clean-shot handling removes cookie banners, newsletter popups, and chat widgets before capture, and bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots.
cURL example, using a search URL as the target:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/search?q=two%20words -o shot.webp
See the ScreenshotNeo API documentation for request options. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Learn about ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




