# Read search params with JS

If you need to read the search params (aka query string) from a URL in JS the most common way is to use [one of the multiple query string parsing libraries on npm](https://www.npmjs.com/search?q=query%20string). But this is not actually needed anymore, both browsers and Node ships with the URL and URLSearchParams classes which help use work with URLs and search params respectively.

## The URL class

If you want to work with a URL and be able to transform it you can use the URL class.

```ts
let url = new URL(window.location.toString())
```

This `url` instance will have attributes to read and update the pathname, host, origin, protocol, etc.

The most interesting ones are `url.search` and `url.searchParams`. The first one is a string with the query string similar to this `?q=query%20string`, this can be used to update the whole query string by doing

```ts
url.search = "?q=something%20else"
```

Now if you run `url.toString()` the full URL string you will get will have the new search.

The `url.searchParams` is an instance of `URLSearchParams`.

## The URLSearchParams class

This class, which can be instantiated manually or read from `url.searchParams`, lets you manipulate the query string without manually working with strings, it has methods similar to the `Map` class of JS so you can do:

```ts
// returns the value of `q`
url.searchParams.get("q")

// returns an array with the values of `q`, useful when the string has `?q=value&q=another` which is valid
url.searchParams.getAll("q")

// replace the value of `q` with `"value"`
url.searchParams.set("q", "value")

// adds another value to `q` so you now have `?q=value&q=another`
url.searchParams.append("q", "another")

// check if the param `q` exists
url.searchParams.has("q")

// removes the param `q` from the search params
url.searchParams.delete("q")

// iterates the list of params and get the value and key, like Array#forEach
url.searchParams.forEach((value, key) => /* do something */)

// the following three methods returns instances of an Iterator, they let you iterate through
// the list of entries (`[key, value]`), the list of keys or the list of values
// you can pass them to `Array.from` to get an array version or use for..of to iterate them
url.searchParams.entries()
url.searchParams.keys()
url.searchParams.values()
```

Once you do any update to the searchParams the value of `url.search` will be automatically updated and the next time you do `url.toString()` you will get the updated version. This only happens if you use `URLSearchParams` through an instance of the `URL` class.

If you manually created an instance of `URLSearchParams` doing:

```ts
// the params is optional, it let you initialize the instance with some values already defined
let searchParams = new URLSearchParams({ q: "value" })
```

Then you can use `searchParams.toString()` to get a string version of your query string and then do:

```ts
url.search = searchParams.toString()
```

To update the search string, note you need to convert it to string and overwrite `url.search` instead of doing:

```ts
// this will not work
url.searchParams = searchParams
```