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;
} 0 31 Answers
12 Next"[&;]?" + parameter + "=[^&;]+"Seems dangerous because it parameter ‘bar’ would match:
?a=b&foobar=cAlso, 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;
} 13 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¶m2=2¶m3=3') console.log(params.toString()) params.delete('param2') console.log(params.toString())
} else { console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)
} 4 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.
3If it's an instance of URL, use the delete function of searchParams
let url = new URL(location.href);
url.searchParams.delete('page'); 1 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.
Copied from bobince answer, but made it support question marks in the query string, eg
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;
} 5 Here a solution that:
- uses URLSearchParams (no difficult to understand regex)
- updates the URL in the search bar without reload
- maintains all other parts of the URL (e.g. hash)
- removes superflous
?in query string if the last parameter was removed
function removeParam(paramName) { let searchParams = new URLSearchParams(window.location.search); searchParams.delete(paramName); if (history.replaceState) { let searchString = searchParams.toString().length > 0 ? '?' + searchParams.toString() : ''; let newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + searchString + window.location.hash; history.replaceState(null, '', newUrl); }
}Note: as pointed out in other answers URLSearchParams is not supported in IE, so use a polyfill.
Here is what I'm using:
if (location.href.includes('?')) { history.pushState({}, null, location.href.split('?')[0]);
}Original URL:
Destination URL:
Now this answer seems even better! (not fully tested though)
2This is a clean version remove query parameter with the URL class for today browsers:
function removeUrlParameter(url, paramKey)
{ var r = new URL(url); r.searchParams.delete(paramKey); return r.href;
}URLSearchParams not supported on old browsers
IE, Edge (below 17) and Safari (below 10.3) do not support URLSearchParams inside URL class.
Polyfills
URLSearchParams only polyfill
Complete Polyfill URL and URLSearchParams to match last WHATWG specifications
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
4Assuming you want to remove key=val parameter from URI:
function removeParam(uri) { return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
} 1 Heres a complete function for adding and removing parameters based on this question and this github gist:
var updateQueryStringParam = function (key, value) { var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''), urlQueryString = document.location.search, newParam = key + '=' + value, params = '?' + newParam; // If the "search" string exists, then build params from it if (urlQueryString) { updateRegex = new RegExp('([\?&])' + key + '[^&]*'); removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?'); if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty params = urlQueryString.replace(removeRegex, "$1"); params = params.replace( /[&;]$/, "" ); } else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it params = urlQueryString.replace(updateRegex, "$1" + newParam); } else { // Otherwise, add it to end of query string params = urlQueryString + '&' + newParam; } } window.history.replaceState({}, "", baseUrl + params);
};You can add parameters like this:
updateQueryStringParam( 'myparam', 'true' );And remove it like this:
updateQueryStringParam( 'myparam', null );In this thread many said that the regex is probably not the best/stable solution ... so im not 100% sure if this thing has some flaws but as far as i tested it it works pretty fine.
Using jQuery:
function removeParam(key) { var url = document.location.href; var params = url.split('?'); if (params.length == 1) return; url = params[0] + '?'; params = params[1]; params = params.split('&'); $.each(params, function (index, value) { var v = value.split('='); if (v[0] != key) url += value + '&'; }); url = url.replace(/&$/, ''); url = url.replace(/\?$/, ''); document.location.href = url;
} The above version as a function
function removeURLParam(url, param)
{ var urlparts= url.split('?'); if (urlparts.length>=2) { var prefix= encodeURIComponent(param)+'='; var pars= urlparts[1].split(/[&;]/g); for (var i=pars.length; i-- > 0;) if (pars[i].indexOf(prefix, 0)==0) pars.splice(i, 1); if (pars.length > 0) return urlparts[0]+'?'+pars.join('&'); else return urlparts[0]; } else return url;
} You should be using a library to do URI manipulation as it is more complicated than it seems on the surface to do it yourself. Take a look at:
From what I can see, none of the above can handle normal parameters and array parameters. Here's one that does.
function removeURLParameter(param, url) { url = decodeURI(url).split("?"); path = url.length == 1 ? "" : url[1]; path = path.replace(new RegExp("&?"+param+"\\[\\d*\\]=[\\w]+", "g"), ""); path = path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), ""); path = path.replace(/^&/, ""); return url[0] + (path.length ? "?" + path : "");
}
function addURLParameter(param, val, url) { if(typeof val === "object") { // recursively add in array structure if(val.length) { return addURLParameter( param + "[]", val.splice(-1, 1)[0], addURLParameter(param, val, url) ) } else { return url; } } else { url = decodeURI(url).split("?"); path = url.length == 1 ? "" : url[1]; path += path.length ? "&" : ""; path += decodeURI(param + "=" + val); return url[0] + "?" + path; }
}How to use it:
url = location.href; ->
url = removeURLParameter("sold", url) ->
url = removeURLParameter("tags", url) ->
url = addURLParameter("tags", ["single", "promo"], url) ->
url = addURLParameter("sold", 1, url) -> Of course, to update a parameter, just remove then add. Feel free to make a dummy function for it.
1All of the responses on this thread have a flaw in that they do not preserve anchor/fragment parts of URLs.
So if your URL looks like:
and you replace 'parameter'
you will lose your fragment text.
The following is adaption of previous answers (bobince via LukePH) that addresses this problem:
function removeParameter(url, parameter)
{ var fragment = url.split('#'); var urlparts= fragment[0].split('?'); if (urlparts.length>=2) { var urlBase=urlparts.shift(); //get first part, and remove from array var queryString=urlparts.join("?"); //join it back up var prefix = encodeURIComponent(parameter)+'='; var pars = queryString.split(/[&;]/g); for (var i= pars.length; i-->0;) { //reverse iteration as may be destructive if (pars[i].lastIndexOf(prefix, 0)!==-1) { //idiom for string.startsWith pars.splice(i, 1); } } url = urlBase + (pars.length > 0 ? '?' + pars.join('&') : ''); if (fragment[1]) { url += "#" + fragment[1]; } } return url;
} 2 I practically wrote the following function to process the url parameters and get the final status as a string and redirect the page. Hopefully it benefits.
function addRemoveUrlQuery(addParam = {}, removeParam = [], startQueryChar = '?'){ let urlParams = new URLSearchParams(window.location.search); //Add param for(let i in addParam){ if(urlParams.has(i)){ urlParams.set(i, addParam[i]); } else { urlParams.append(i, addParam[i]); } } //Remove param for(let i of removeParam){ if(urlParams.has(i)){ urlParams.delete(i); } } if(urlParams.toString()){ return startQueryChar + urlParams.toString(); } return '';
}For example, when I click a button, I want the page value to be deleted and the category value to be added.
let button = document.getElementById('changeCategory');
button.addEventListener('click', function (e) { window.location = addRemoveUrlQuery({'category':'cars'}, ['page']);
});I think it was very useful!
another direct & simpler answer would be
let url = new URLSearchParams(location.search)
let key = 'some_key'
return url.has(key) ? location.href.replace(new RegExp(`[?&]${key}=${url.get(key)}`), '') : location.href Glad you scrolled here.
I would suggest you to resolve this task by next possible solutions:
- You need to support only modern browsers (Edge >= 17) - use URLSearchParams.delete() API. It is native and obviously is the most convenient way of solving this task.
- If this is not an option, you may want to write a function to do this. Such a function does
- do not change URL if a parameter is not present
- remove URL parameter without a value, like
- remove URL parameter with a value, like
- remove URL parameter if is it in URL twice, like
- Does not use
forloop and not modify array during looping over it - is more functional
- is more readable than regexp solutions
- Before using make sure your URL is not encoded
Works in IE > 9 (ES5 version)
function removeParamFromUrl(url, param) { // url: string, param: string var urlParts = url.split('?'), preservedQueryParams = ''; if (urlParts.length === 2) { preservedQueryParams = urlParts[1] .split('&') .filter(function(queryParam) { return !(queryParam === param || queryParam.indexOf(param + '=') === 0) }) .join('&'); } return urlParts[0] + (preservedQueryParams && '?' + preservedQueryParams);
}Fancy ES6 version
function removeParamFromUrlEs6(url, param) { const [path, queryParams] = url.split('?'); let preservedQueryParams = ''; if (queryParams) { preservedQueryParams = queryParams .split('&') .filter(queryParam => !(queryParam === param || queryParam.startsWith(`${param}=`))) .join('&'); } return `${path}${preservedQueryParams && `?${preservedQueryParams}`}`;
} If you have a polyfill for URLSearchParams or simply don't have to support Internet Explorer, that's what I would use like suggested in other answers here. If you don't want to depend on URLSearchParams, that's how I would do it:
function removeParameterFromUrl(url, parameter) { const replacer = (m, p1, p2) => (p1 === '?' && p2 === '&' ? '?' : p2 || '') return url.replace(new RegExp(`([?&])${parameter}=[^&#]+([&#])?`), replacer)
}It will replace a parameter preceded by ? (p1) and followed by & (p2) with ? to make sure the list of parameters still starts with a question mark, otherwise, it will replace it with the next separator (p2): could be &, or #, or undefined which falls back to an empty string.
Here's a simple non-regex way to get rid of all query params:
const url = "";
const urlObj = new URL(url);
const urlWithoutQueryParams = `${urlObj.origin}${urlObj.pathname}`; Here is a better a way to remove any query param from url and update the URL (if needed)
const myUrl = '
const newUrl = new URL(myUrl);
// delete any param (lets say 'temp' in our case)
newUrl.searchParams.delete('temp');
console.log(newUrl.href); //
//set any param (lets say 'newParam' in our case)
newUrl.searchParams.set('newParam', 20);
console.log(newUrl.href) // // If you want to set the updated URL with no page reload, then use the History API as:
history.replaceState({}, null, newUrl.href); A modified version of solution by ssh_imov
function removeParam(uri, keyValue) { var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i"); return uri.replace(re, ''); }Call like this
removeParam("", "q1=234");
// returns 1 This returns the URL w/o ANY GET Parameters:
var href = document.location.href;
var search = document.location.search;
var pos = href.indexOf( search );
if ( pos !== -1 ){ href = href.slice( 0, pos ); console.log( href );
} const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString()) 1 function removeParamInAddressBar(parameter) { var url = document.location.href; var urlparts = url.split('?'); if (urlparts.length >= 2) { var urlBase = urlparts.shift(); var queryString = urlparts.join("?"); var prefix = encodeURIComponent(parameter) + '='; var pars = queryString.split(/[&;]/g); for (var i = pars.length; i-- > 0;) { if (pars[i].lastIndexOf(prefix, 0) !== -1) { pars.splice(i, 1); } } if (pars.length == 0) { url = urlBase; } else { url = urlBase + '?' + pars.join('&'); } window.history.pushState('', document.title, url); // push the new url in address bar } return url;
} function clearQueryParams() { const paramName = 'abc'; const url = new URL(window.location.href); url.searchParams.delete(paramName); const newUrl = url.search ? url.href : url.href.replace('?', ''); window.history.replaceState({}, document.title, newUrl); //if you don't want to reload window.location = newUrl; //if you want to reload
} const removeQueryParams = (url: string) => { const urlParts = url.split("?"); return urlParts[0];
}; If you're into jQuery, there is a good query string manipulation plugin:
2 12 Next