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; }
031 Answers
1 2 Next"[&;]?" + 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; }
13Modern 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`) }
4You 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');
1I 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
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; }
5Here a solution that:
?
in query string if the last parameter was removedfunction 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: http://www.example.com/test/hello?id=123&foo=bar
Destination URL: http://www.example.com/test/hello
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
https://caniuse.com/#feat=urlsearchparams
IE, Edge (below 17) and Safari (below 10.3) do not support URLSearchParams inside URL class.
Polyfills
URLSearchParams only polyfill
https://github.com/WebReflection/url-search-params
Complete Polyfill URL and URLSearchParams to match last WHATWG specifications
https://github.com/lifaon74/url-polyfill
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(?=#))/, ''); }
1Heres a complete function for adding and removing parameters based on this question and this github gist: https://gist.github.com/excalq/2961415
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: http://medialize.github.io/URI.js/
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; -> http://example.com/?tags[]=single&tags[]=promo&sold=1 url = removeURLParameter("sold", url) -> http://example.com/?tags[]=single&tags[]=promo url = removeURLParameter("tags", url) -> http://example.com/ url = addURLParameter("tags", ["single", "promo"], url) -> http://example.com/?tags[]=single&tags[]=promo url = addURLParameter("sold", 1, url) -> http://example.com/?tags[]=single&tags[]=promo&sold=1
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:
http://dns-entry/path?parameter=value#fragment-text
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; }
2I 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:
- do not change URL if a parameter is not present
- remove URL parameter without a value, like
http://google.com/?myparm
- remove URL parameter with a value, like
http://google.com/?myparm=1
- remove URL parameter if is it in URL twice, like
http://google.com?qp=1&qpqp=2&qp=1
- Does not use
for
loop 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 = "https://example.com"; 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 = 'https://example.com?val=3&temp=20' const newUrl = new URL(myUrl); // delete any param (lets say 'temp' in our case) newUrl.searchParams.delete('temp'); console.log(newUrl.href); // https://example.com/?val=3 //set any param (lets say 'newParam' in our case) newUrl.searchParams.set('newParam', 20); console.log(newUrl.href) // // https://example.com/?val=3&newParam=20
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("http://google.com?q=123&q1=234&q2=567", "q1=234"); // returns http://google.com?q=123&q2=567
1This 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())
1function 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 1 2 Next Answer This QuestionncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoaG9rZGyBeXvHqK5mm5Gjeqp5w56jnqyVYq5uvdSeqbJlo6m%2FqrrGZqeaqpGisrWx0Wagp2WalsOiv8KroKms