How can I delete a query string parameter in JavaScript?

How can I delete a query string parameter in JavaScript?

Is there better way to delete a parameter from a query string in a URL string in standard JavaScript other than by using a regular expression?
Here’s what I’ve come up with so far which seems to work in my tests, but I don’t like to reinvent querystring parsing!
function RemoveParameterFromUrl( url, parameter ) {

if( typeof parameter == “undefined” || parameter == null || parameter == “” ) throw new Error( “parameter is required” );

url = url.replace( new RegExp( “\\b” + parameter + “=[^&;]+[&;]?”, “gi” ), “” ); “$1” );

// remove any leftover crud
url = url.replace( /[&;]$/, “” );

return url;
}

Solutions/Answers:

Solution 1:

"[&;]?" + parameter + "=[^&;]+"

Seems dangerous because it parameter ‘bar’ would match:

?a=b&foobar=c

Also, it would fail if parameter contained any characters that are special in RegExp, such as ‘.’. And it’s not a global regex, so it would only remove one instance of the parameter.

I wouldn’t use a simple RegExp for this, I’d parse the parameters in and lose the ones you don’t want.

function removeURLParameter(url, parameter) {
    //prefer to use l.search if you have a location/link object
    var urlparts = url.split('?');   
    if (urlparts.length >= 2) {

        var prefix = encodeURIComponent(parameter) + '=';
        var pars = urlparts[1].split(/[&;]/g);

        //reverse iteration as may be destructive
        for (var i = pars.length; i-- > 0;) {    
            //idiom for string.startsWith
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
                pars.splice(i, 1);
            }
        }

        return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
    }
    return url;
}

Solution 2:

Copied from bobince answer, but made it support question marks in the query string, eg

http://www.google.com/search?q=test???+something&aq=f

Is it valid to have more than one question mark in a URL?

function removeUrlParameter(url, parameter) {
  var urlParts = url.split('?');

  if (urlParts.length >= 2) {
    // Get first part, and remove from array
    var urlBase = urlParts.shift();

    // Join it back up
    var queryString = urlParts.join('?');

    var prefix = encodeURIComponent(parameter) + '=';
    var parts = queryString.split(/[&;]/g);

    // Reverse iteration as may be destructive
    for (var i = parts.length; i-- > 0; ) {
      // Idiom for string.startsWith
      if (parts[i].lastIndexOf(prefix, 0) !== -1) {
        parts.splice(i, 1);
      }
    }

    url = urlBase + '?' + parts.join('&');
  }

  return url;
}

Solution 3:

Modern browsers provide URLSearchParams interface to work with search params. Which has delete method that removes param by name.

if (typeof URLSearchParams !== 'undefined') {
  const params = new URLSearchParams('param1=1&param2=2&param3=3')
  
  console.log(params.toString())
  
  params.delete('param2')
  
  console.log(params.toString())

} else {
  console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)
}

Solution 4:

I don’t see major issues with a regex solution. But, don’t forget to preserve the fragment identifier (text after the #).

Here’s my solution:

function RemoveParameterFromUrl(url, parameter) {
  return url
    .replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?$'), '$1')
    .replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}

And to bobince’s point, yes – you’d need to escape . characters in parameter names.

Solution 5:

Anyone interested in a regex solution I have put together this function to add/remove/update a querystring parameter. Not supplying a value will remove the parameter, supplying one will add/update the paramter. If no URL is supplied, it will be grabbed from window.location. This solution also takes the url’s anchor into consideration.

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null)
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
        else
            return url;
    }
}

UPDATE

There was a bug when removing the first parameter in the querystring, I have reworked the regex and test to include a fix.

UPDATE 2

@schellmax update to fix situation where hashtag symbol is lost when removing a querystring variable directly before a hashtag

Solution 6:

You can change the URL with:

window.history.pushState({}, document.title, window.location.pathname);

this way, you can overwrite the URL without the search parameter, I use it to clean the URL after take the GET parameters.