TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Read and Modify URL Parameters in JavaScript

Practical insights, clear explanations, and useful ideas for understanding the web.

October 25, 20265 min read5 topics
How to Read and Modify URL Parameters in JavaScript
Explore the details
#JavaScript#URLSearchParams#Web APIs#URL parameters#Web development
October 25, 20265 min read

URLs often carry useful data in their query string: a search term, a page number, or a filter. In JavaScript, the built-in URLSearchParams API makes it easier to read and update those parameters without manually splitting strings or encoding values. This tutorial covers common operations, encoding behavior, and mistakes to avoid.

Key takeaways

  • Use URLSearchParams to read and modify query-string parameters.
  • Use getAll() when a parameter may appear more than once; get() returns only its first value.
  • Use the URL object when you need to preserve and update the rest of a URL.
  • set() replaces values for a key, while append() adds another value.
  • Query parameters are user-controlled input, so validate values before relying on them.

Create URLSearchParams and read values

You can construct URLSearchParams from a query string. The initial ? is optional:

const params = new URLSearchParams("?q=javascript&page=2");

console.log(params.get("q"));    // "javascript"
console.log(params.get("page")); // "2"
console.log(params.has("q"));    // true
console.log(params.has("sort")); // false

Values returned by get() are strings. Convert them when your application needs a number, and validate the result rather than assuming it is usable:

const params = new URLSearchParams("page=3");
const rawPage = params.get("page");
const page = Number(rawPage);

if (rawPage !== null && Number.isInteger(page) && page > 0) {
  console.log(`Show page ${page}`);
} else {
  console.log("Use the default page");
}

get() returns null if the key is absent. An empty value, such as ?q=, is different: get("q") returns an empty string.

Read parameters from a full URL or the current page

URLSearchParams handles a query string, not an entire URL. For a complete URL, create a URL object and access its searchParams property:

const url = new URL("https://example.com/products?category=books&page=2");

console.log(url.searchParams.get("category")); // "books"
console.log(url.searchParams.get("page"));     // "2"

In a browser, use the current page URL's search parameters:

const params = new URLSearchParams(window.location.search);
const searchTerm = params.get("q");

console.log(searchTerm);

For a relative URL such as /products?page=2, provide a base when constructing a URL:

const url = new URL("/products?page=2", window.location.origin);
console.log(url.searchParams.get("page")); // "2"

For a quick visual check of a query string, you can also use the TidyURLs query editor. Treat any values you inspect there, or receive in your application, as input that may need validation.

Handle repeated parameters

A query string can contain the same key more than once, for example ?tag=javascript&tag=web. get() returns the first value; use getAll() to retrieve every value:

const params = new URLSearchParams("tag=javascript&tag=web");

console.log(params.get("tag"));    // "javascript"
console.log(params.getAll("tag")); // ["javascript", "web"]

This distinction matters when a page supports multiple selections or when an API expects repeated keys. Check the receiving application's expected format before choosing between repeated parameters and a single delimited value.

Modify parameters with set, append, and delete

Use set() to create a key or replace its existing values. If that key occurs multiple times, set() leaves one value for it. Use append() when you intentionally want an additional occurrence. Use delete() to remove a key:

const params = new URLSearchParams("tag=javascript&tag=web&page=1");

params.set("page", "2");
params.append("tag", "accessibility");
params.delete("page");

console.log(params.toString());
// "tag=javascript&tag=web&tag=accessibility"

To update a full URL while preserving its other components, work through URL.searchParams:

const url = new URL("https://example.com/search?q=old&page=1");

url.searchParams.set("q", "URL parameters");
url.searchParams.set("page", "2");

console.log(url.href);
// "https://example.com/search?q=URL+parameters&page=2"

URLSearchParams handles query-string serialization for you. If you need to inspect the resulting encoding, toString() returns the serialized query without a leading ?.

Encode and serialize values safely

Pass unencoded values to set() or append() and let the API serialize them. Avoid encoding a value first with encodeURIComponent(), which can lead to double encoding:

const params = new URLSearchParams();
params.set("q", "red shoes & socks");

console.log(params.toString());
// "q=red+shoes+%26+socks"

When reading values, URLSearchParams decodes them. In form-style query serialization, spaces are represented as +; encoded plus signs are represented differently. Do not treat a query string's raw spelling as its decoded value.

You can also provide an object of simple string values:

const params = new URLSearchParams({
  q: "javascript",
  page: "2"
});

console.log(params.toString()); // "q=javascript&page=2"

If a value is an array, this object form does not automatically create repeated keys for each array element. Use append() when repeated keys are required.

A practical workflow for updating a link

Use this pattern when building a link from an existing URL:

  1. Parse the URL with new URL() and provide a base if it is relative.
  2. Read existing values through url.searchParams.
  3. Validate values that came from users or external sources.
  4. Update parameters with set(), append(), or delete() as appropriate.
  5. Use url.href for the complete serialized URL.
function buildSearchUrl(input, baseUrl) {
  const url = new URL(input, baseUrl);
  const pageValue = url.searchParams.get("page");
  const page = Number(pageValue);

  if (pageValue !== null && (!Number.isInteger(page) || page < 1)) {
    url.searchParams.delete("page");
  }

  url.searchParams.set("source", "site-search");
  return url.href;
}

const result = buildSearchUrl(
  "/search?q=books&page=2",
  "https://example.com"
);

console.log(result);

This example normalizes an invalid page value and adds a source parameter. In a real application, adapt validation and allowed values to the requirements of the feature.

Common mistakes and pitfalls

Passing a complete URL to URLSearchParams

new URLSearchParams("https://example.com/?q=test") does not parse the URL into its components. Parse the complete URL with new URL() first, then use url.searchParams.

Assuming all values are numbers or booleans

Query parameters are text. Convert and validate values explicitly. For booleans, define which strings your application accepts, such as "true" and "false", instead of relying on JavaScript truthiness.

Losing repeated values with set()

set() replaces the existing values for a key. Use append() to add another value, and getAll() to read repeated values.

Comparing serialized strings without considering normalization

Different query-string spellings can represent the same decoded value, and serialization may normalize their encoding. Compare parsed names and values when that is the intended comparison rather than assuming the raw strings will be identical.

Treating URL parsing as input validation

Parsing a query parameter does not establish that it is safe, authorized, or appropriate for a particular operation. Validate against the application's expected type, range, and allowed values. If a value is later used in a sensitive operation, apply the security controls required for that operation as well.

Conclusion

URLSearchParams provides a straightforward way to read, serialize, and modify query parameters in JavaScript. Use URL for complete URLs, choose getAll() or append() when repeated keys matter, and validate values before using them. These habits make query-string handling clearer and less error-prone.

References