Skip to content

Instantly share code, notes, and snippets.

@niyazpk
Created October 25, 2014 14:03
Show Gist options
  • Star 67 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save niyazpk/f8ac616f181f6042d1e0 to your computer and use it in GitHub Desktop.
Save niyazpk/f8ac616f181f6042d1e0 to your computer and use it in GitHub Desktop.
Add or update query string parameter
// Add / Update a key-value pair in the URL query parameters
function updateUrlParameter(uri, key, value) {
// remove the hash part before operating on the uri
var i = uri.indexOf('#');
var hash = i === -1 ? '' : uri.substr(i);
uri = i === -1 ? uri : uri.substr(0, i);
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
uri = uri.replace(re, '$1' + key + "=" + value + '$2');
} else {
uri = uri + separator + key + "=" + value;
}
return uri + hash; // finally append the hash as well
}
@insign
Copy link

insign commented Nov 23, 2014

Great fix.

@amorgner
Copy link

Found the script (thanks for publishing it) and added the option to remove a key-value pair:

function updateUrlParameter(uri, key, value) {
  // remove the hash part before operating on the uri
  var i = uri.indexOf('#');
  var hash = i === -1 ? ''  : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);

  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([&]?)" + key + "=.*?(&|$)", "i"), '');
    if (uri.slice(-1) === '?') {
      uri = uri.slice(0, -1);
    }
  } else if (uri.match(re)) {
    uri = uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    uri = uri + separator + key + "=" + value;
  }
  return uri + hash;
}

The script doesn't have a license header. Am I allowed to use the script including my modifications?

@amorgner
Copy link

amorgner commented Apr 5, 2016

My above version had a bug when removing a URL parameter in the middle, e.g. ?a=1&b=2&c=3 => ?a=1&c=3. This should work with the following version:

function updateUrlParameter(uri, key, value) {
  // remove the hash part before operating on the uri
  var i = uri.indexOf('#');
  var hash = i === -1 ? ''  : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);

  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";

  if (!value) {
    // remove key-value pair if value is empty
    uri = uri.replace(new RegExp("([?&]?)" + key + "=[^&]*", "i"), '');
    if (uri.slice(-1) === '?') {
      uri = uri.slice(0, -1);
    }
    // replace first occurrence of & by ? if no ? is present
    if (uri.indexOf('?') === -1) uri = uri.replace(/&/, '?');
  } else if (uri.match(re)) {
    uri = uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    uri = uri + separator + key + "=" + value;
  }
  return uri + hash;
}

@williamtguerra
Copy link

thanks for the update

@GDmac
Copy link

GDmac commented Oct 27, 2016

Nice, but if there are already two of the same keys, then it will only find/replace the first found. But server side (PHP) the last found will actually be set in GET vars

@simsketch
Copy link

Thanks @amorgner...gets the job done for me!

@mystroken
Copy link

Thanks guys... you just saved me hours of work lol

@gitanupam
Copy link

Nice work @niyazpk and @amorgner - quite helpful!

@chewett
Copy link

chewett commented Sep 21, 2020

Update to amorgner's code to allow setting falsy values.

I wanted to be able to set 0 and similar "falsy" values in the URL so I have modified it so only remove a value if null is specifically passed in.

Otherwise anything that evaluated to false would unset, which wasnt he behaviour I wanted.

Tweaked code: https://gist.github.com/niyazpk/f8ac616f181f6042d1e0#gistcomment-1743025

Thanks all to those improving this, pass it on 👍

function updateUrlParameter(uri, key, value) {
    // remove the hash part before operating on the uri
    var i = uri.indexOf('#');
    var hash = i === -1 ? ''  : uri.substr(i);
    uri = i === -1 ? uri : uri.substr(0, i);

    var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";

    if (value === null) {
        // remove key-value pair if value is specifically null
        uri = uri.replace(new RegExp("([?&]?)" + key + "=[^&]*", "i"), '');
        if (uri.slice(-1) === '?') {
            uri = uri.slice(0, -1);
        }
        // replace first occurrence of & by ? if no ? is present
        if (uri.indexOf('?') === -1) uri = uri.replace(/&/, '?');
    } else if (uri.match(re)) {
        uri = uri.replace(re, '$1' + key + "=" + value + '$2');
    } else {
        uri = uri + separator + key + "=" + value;
    }
    return uri + hash;
}

@chenyuantao
Copy link

Typescript version

Tweaked code: https://gist.github.com/niyazpk/f8ac616f181f6042d1e0#gistcomment-3461639

Thanks all to those improving this, pass it on 👍

const updateUrlParameter = (uri: string, key: string, value: string | null) => {
  // remove the hash part before operating on the uri
  const i = uri.indexOf('#');
  const hash = i === -1 ? '' : uri.substr(i);
  uri = i === -1 ? uri : uri.substr(0, i);

  const re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
  const separator = uri.indexOf('?') !== -1 ? '&' : '?';

  if (value === null) {
    // remove key-value pair if value is specifically null
    uri = uri.replace(new RegExp(`([?&]?)${key}=[^&]*`, 'i'), '');
    if (uri.slice(-1) === '?') {
      uri = uri.slice(0, -1);
    }
    // replace first occurrence of & by ? if no ? is present
    if (uri.indexOf('?') === -1) uri = uri.replace(/&/, '?');
  } else if (uri.match(re)) {
    uri = uri.replace(re, `$1${key}=${value}$2`);
  } else {
    uri = `${uri + separator + key}=${value}`;
  }
  return uri + hash;
};

@Leksat
Copy link

Leksat commented Aug 24, 2021

It worth to publish it on NPM. I was really surprised today that there is no package to manipulate non-absolute URLs 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment