81

If I had a URL such as

http://localhost/search.php?year=2008 

How would I write a JavaScript function to grab the variable year and see if it contains anything?

I know it can be done with location.search but I can’t figure out how it grabs parameters.

4
  • string yr = location.search.substring(6); alert(yr); Commented Oct 31, 2013 at 18:36
  • 13
    location.search.split("year=")[1] only in simplest Commented Dec 16, 2013 at 7:30
  • 2
    Looks like the question is closed but the most current answer isn't here: new URLSearchParams(location.search).get('year') Commented Dec 31, 2019 at 23:07
  • You can use URLSearchParams.getAll() to return all of the values associated with a particular parameter: console.log(urlParams.getAll('size')); Commented May 5, 2021 at 1:41

14 Answers 14

87

You may use window.URL class:

new URL(location.href).searchParams.get('year') // Returns 2008 for href = "http://localhost/search.php?year=2008". // Or in two steps: const params = new URL(location.href).searchParams; const year = params.get('year'); 
Sign up to request clarification or add additional context in comments.

4 Comments

window.URL is a handy one, if only using latest Chrome and Firefox
this shuld be the accepted answer nowadays
@pungggi ...until your client uses internet explorer :(
@haykam Then use a polyfill for that!
59

My favorite way for getting URL params is this approach:

var parseQueryString = function() { var str = window.location.search; var objURL = {}; str.replace( new RegExp( "([^?=&]+)(=([^&]*))?", "g" ), function( $0, $1, $2, $3 ){ objURL[ $1 ] = $3; } ); return objURL; }; //Example how to use it: var params = parseQueryString(); alert(params["foo"]); 

5 Comments

That old man always says "when you have a problem that can only be resolved with regular expressions, you actually have two problems".
I love this, very cute! is there a reason you capture the '='? you could say /([^?=&]+)=([^&]*)/g and have your params be (match, key, value)?
isn't location.search.split("year=")[1] much simpler?
@Rodrigo if you have more than one params it will blow
A more elegant —no regex / more modern (2018) — solution is here: stackoverflow.com/a/42316411/328117
56

A non-regex approach, you can simply split by the character '&' and iterate through the key/value pair:

function getParameter(paramName) { var searchString = window.location.search.substring(1), i, val, params = searchString.split("&"); for (i=0;i<params.length;i++) { val = params[i].split("="); if (val[0] == paramName) { return val[1]; } } return null; } 

2020 EDIT:

Nowadays, in modern browsers you can use the URLSearchParams constructor:

const params = new URLSearchParams('?year=2020&month=02&day=01') // You can access specific parameters: console.log(params.get('year')) console.log(params.get('month')) // And you can iterate over all parameters for (const [key, value] of params) { console.log(`Key: ${key}, Value: ${value}`); }

5 Comments

Isn't val a global in there?
then can i do if(getParameter("year") != "") { var year=getParameter("year"); document.location.href=page.php?year=$year&etc etc.
@sarmenhb: You can do: var year=getParameter("year"); if (year){ document.location.href='page.php?year='+year;}
@Luca Matteis: No, val is not a global in there. It's defined as a local var in var searchString, i, val, ...
Elegant and easy to use! Why isn't this marked as the answer?
21

Edit 2024

URLSearchParams is the way to go now.

const params = new URLSearchParams(location.search) params.get("year") // => 2008 

Edit 2020

You can convert URL params to an Object:

const params = location.search.slice(1).split('&').reduce((acc, s) => { const [k, v] = s.split('=') return Object.assign(acc, {[k]: v}) }, {}) 

Then it can be used as a regular JS Object:

params.year // 2008 

Older update

const params = new Map(location.search.slice(1).split('&').map(kv => kv.split('='))) 

You can then test if the year param exists with:

params.has('year') // true 

Or retrieve it with:

params.get('year') // 2008 

Older way

This question is old and things have evolved in JavaScript. You can now do this:

const params = {} document.location.search.substr(1).split('&').forEach(pair => { [key, value] = pair.split('=') params[key] = value }) 

and you get params.year that contains 2008. You would also get other query params in your params object.

4 Comments

You should use a .reduce() instead of .forEach
Doesn't work with .reduce(). Only first param is written to params object. Checked in Chrome dev tools. Can you please double check and and replace with forEach() instead?
@vinyll @tylik const getQueryObject = locationSearchString => locationSearchString .substr(1) .split('&') .reduce((queryObject, keyValuePair) => { const [key, value] = keyValuePair.split('='); queryObject[key] = value; return queryObject; }, {});
you should use URL but if you're going to do it this way you need to call decodeURIComponent on every key and value after splitting by & and =. This is how it's possible to encode = and & in the keys and values themselves as well as other things like # as they'll all be encoded.
8

The following uses regular expressions and searches only on the query string portion of the URL.

Most importantly, this method supports normal and array parameters as in http://localhost/?fiz=zip&foo[]=!!=&bar=7890#hashhashhash

function getQueryParam(param) { var result = window.location.search.match( new RegExp("(\\?|&)" + param + "(\\[\\])?=([^&]*)") ); return result ? result[3] : false; } console.log(getQueryParam("fiz")); console.log(getQueryParam("foo")); console.log(getQueryParam("bar")); console.log(getQueryParam("zxcv")); 

Output:

zip !!= 7890 false 

Comments

6

It took me a while to find the answer to this question. Most people seem to be suggesting regex solutions. I strongly prefer to use code that is tried and tested as opposed to regex that I or someone else thought up on the fly.

I use the parseUri library available here: http://stevenlevithan.com/demo/parseuri/js/

It allows you to do exactly what you are asking for:

var uri = 'http://localhost/search.php?year=2008'; var year = uri.queryKey['year']; // year = '2008' 

1 Comment

var year = parseUri(window.location.search).queryKey['year']; Is a more relevant example. The one above does not work with version 1.2 of the parseUri script.
6
function gup( name ) { name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); var regexS = "[\\?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec( window.location.href ); if( results == null ) return ""; else return results[1]; } var year = gup("year"); // returns "2008" 

2 Comments

You should use window.location.search instead of window.location.href. This would simplify your expressions not having to check for the hash or query markers
It would be a good idea to escape all regex meta characters in "name" before creating a regex off of it.
5

The easiest way is to have

if (document.location.search.indexOf('yourtext=') >= 0) { // your code } else { // what happens? } 

indexOf()

The indexOf(text) function returns

  • A WHOLE NUMBER BELOW 0 when the text passed in the function is not in whatever variable or string you are looking for - in this case document.location.search.
  • A WHOLE NUMBER EQUAL TO 0 OR HIGHER when the text passed in the function is in whatever variable or string you are looking for - in this case document.location.search.

I hope this was useful, @gumbo

2 Comments

This fails with a query string like ?notyourtext=foo
...and fails when using ?yourtext=foo&notyourtext=bar.
4

A Simple One-Line Solution:

let query = Object.assign.apply(null, location.search.slice(1).split('&').map(entry => ({ [entry.split('=')[0]]: entry.split('=')[1] }))); 

Expanded & Explained:

// define variable let query; // fetch source query query = location.search; // skip past the '?' delimiter query = query.slice(1); // split source query by entry delimiter query = query.split('&'); // replace each query entry with an object containing the query entry query = query.map((entry) => { // get query entry key let key = entry.split('=')[0]; // get query entry value let value = entry.split('=')[1]; // define query object let container = {}; // add query entry to object container[key] = value; // return query object return container; }); // merge all query objects query = Object.assign.apply(null, query); 

Comments

1

I used a variant of Alex's - but needed to to convert the param appearing multiple times to an array. There seem to be many options. I didn't want rely on another library for something this simple. I suppose one of the other options posted here may be better - I adapted Alex's because of the straight forwardness.

parseQueryString = function() { var str = window.location.search; var objURL = {}; // local isArray - defer to underscore, as we are already using the lib var isArray = _.isArray str.replace( new RegExp( "([^?=&]+)(=([^&]*))?", "g" ), function( $0, $1, $2, $3 ){ if(objURL[ $1 ] && !isArray(objURL[ $1 ])){ // if there parameter occurs more than once, convert to an array on 2nd var first = objURL[ $1 ] objURL[ $1 ] = [first, $3] } else if(objURL[ $1 ] && isArray(objURL[ $1 ])){ // if there parameter occurs more than once, add to array after 2nd objURL[ $1 ].push($3) } else { // this is the first instance objURL[ $1 ] = $3; } } ); return objURL; }; 

1 Comment

If a param appears more than once, it should only be treated as an array if it ends with [] (e.g. foo[]=1&foo[]=2). Otherwise, you should use either the first or last occurrence.
1

I played a bit with this problem and at this end I used this:

function getJsonFromUrl() { return Object.assign(...location.search.substr(1).split("&").map(sliceProperty)); } 
  • Object.assign to transform a list of object into one object
  • Spread operator ... to transform an array into a list
  • location.search.substr(1).split("&") to get all parameters as array of properties (foo=bar)
  • map walk each properties and split them into an array (either call splitProperty or sliceProperty).

splitProperty:

 function splitProperty(pair) { [key, value] = pair.split("=") return { [key]: decodeURIComponent(value) } } 
  • Split by =
  • Deconstruct the array into an array of two elements
  • Return a new object with the dynamic property syntax

sliceProperty:

 function sliceProperty(pair) { const position = pair.indexOf("="), key = pair.slice(0, position), value = pair.slice(position + 1, pair.length); return { [key]: decodeURIComponent(value) } } 
  • Set the position of =, key and value
  • Return a new object with the dynamic property syntax

I think splitProperty is prettier but sliceProperty is faster. Run JsPerf for more information.

Comments

1

Grab the params from location.search with one line:

const params = new Map(this.props.location.search.slice(1).split('&').map(param => param.split('='))) 

Then, simply:

if(params.get("year")){ //year exists. do something... } else { //year doesn't exist. do something else... } 

Comments

0

ES6 answer:

const parseQueryString = (path = window.location.search) => path.slice(1).split('&').reduce((car, cur) => { const [key, value] = cur.split('=') return { ...car, [key]: value } }, {}) 

for example:

parseQueryString('?foo=bar&foobar=baz') // => {foo: "bar", foobar: "baz"} 

Comments

0

This is what I like to do:

window.location.search .substr(1) .split('&') .reduce( function(accumulator, currentValue) { var pair = currentValue .split('=') .map(function(value) { return decodeURIComponent(value); }); accumulator[pair[0]] = pair[1]; return accumulator; }, {} ); 

Of course you can make it more compact using modern syntax or writing everything into one line...

I leave that up to you.

Comments