Instantly share code, notes, and snippets.

Embed
What would you like to do?
Javacript: Set or Update a URL/QueryString Parameter, and update URL using HTML history.replaceState()
// Explicitly save/update a url parameter using HTML5's replaceState().
function updateQueryStringParam(param, value) {
baseUrl = [location.protocol, '//', location.host, location.pathname].join('');
urlQueryString = document.location.search;
var newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
keyRegex = new RegExp('([\?&])' + key + '[^&]*');
// If param exists already, update it
if (urlQueryString.match(keyRegex) !== null) {
params = urlQueryString.replace(keyRegex, "$1" + newParam);
} else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
window.history.replaceState({}, "", baseUrl + params);
}
@wickedest

This comment has been minimized.

Show comment
Hide comment
@wickedest

wickedest Jun 22, 2015

Thanks for the code snippet. The arguments are wrong - this should be: updateQueryStringParam(key, value)

wickedest commented Jun 22, 2015

Thanks for the code snippet. The arguments are wrong - this should be: updateQueryStringParam(key, value)

@leye0

This comment has been minimized.

Show comment
Hide comment
@leye0

leye0 Nov 10, 2015

It navigates instead of replacing.

leye0 commented Nov 10, 2015

It navigates instead of replacing.

@mattandrews

This comment has been minimized.

Show comment
Hide comment
@mattandrews

mattandrews Feb 25, 2016

Thanks for this – here's a slightly fixed version with the correct argument names and proper var declarations:

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) {
        keyRegex = new RegExp('([\?&])' + key + '[^&]*');

        // If param exists already, update it
        if (urlQueryString.match(keyRegex) !== null) {
            params = urlQueryString.replace(keyRegex, "$1" + newParam);
        } else { // Otherwise, add it to end of query string
            params = urlQueryString + '&' + newParam;
        }
    }
    window.history.replaceState({}, "", baseUrl + params);
};

mattandrews commented Feb 25, 2016

Thanks for this – here's a slightly fixed version with the correct argument names and proper var declarations:

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) {
        keyRegex = new RegExp('([\?&])' + key + '[^&]*');

        // If param exists already, update it
        if (urlQueryString.match(keyRegex) !== null) {
            params = urlQueryString.replace(keyRegex, "$1" + newParam);
        } else { // Otherwise, add it to end of query string
            params = urlQueryString + '&' + newParam;
        }
    }
    window.history.replaceState({}, "", baseUrl + params);
};
@johannesgrandy

This comment has been minimized.

Show comment
Hide comment
@johannesgrandy

johannesgrandy Nov 17, 2016

@mattandrews: great stuff. Amazing would be if the url parameter gets removed if no value is entered.

johannesgrandy commented Nov 17, 2016

@mattandrews: great stuff. Amazing would be if the url parameter gets removed if no value is entered.

@johannesgrandy

This comment has been minimized.

Show comment
Hide comment
@johannesgrandy

johannesgrandy Nov 17, 2016

Here is a quick idea based on this stackoverflow answer:
http://stackoverflow.com/questions/1634748/how-can-i-delete-a-query-string-parameter-in-javascript

Not sure if its stable like this ... regex is not one of my strengths

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);
};

johannesgrandy commented Nov 17, 2016

Here is a quick idea based on this stackoverflow answer:
http://stackoverflow.com/questions/1634748/how-can-i-delete-a-query-string-parameter-in-javascript

Not sure if its stable like this ... regex is not one of my strengths

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);
};
@talamihg

This comment has been minimized.

Show comment
Hide comment
@talamihg

talamihg Jan 20, 2017

This is awesome! Gave it a test, and when passing a blank 'value' or just the 'key' and no value, it will remove the query string from the url. Nice!

talamihg commented Jan 20, 2017

This is awesome! Gave it a test, and when passing a blank 'value' or just the 'key' and no value, it will remove the query string from the url. Nice!

@rustam87

This comment has been minimized.

Show comment
Hide comment
@rustam87

rustam87 Jun 16, 2017

Not working, for example EventSearch[date] param RegExp return null

rustam87 commented Jun 16, 2017

Not working, for example EventSearch[date] param RegExp return null

@hellojebus

This comment has been minimized.

Show comment
Hide comment
@hellojebus

hellojebus Aug 7, 2017

@johannesgrandy beautiful, exactly what I was looking for. Now time to back to all my code and refactor haha

hellojebus commented Aug 7, 2017

@johannesgrandy beautiful, exactly what I was looking for. Now time to back to all my code and refactor haha

@DominikAngerer

This comment has been minimized.

Show comment
Hide comment
@DominikAngerer

DominikAngerer Aug 17, 2017

added params = params == '?' ? '' : params; otherwise a ? would stay even there are no more params left.

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) {
        var updateRegex = new RegExp('([\?&])' + key + '[^&]*');
        var 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;
        }
    }

    // no parameter was set so we don't need the question mark
    params = params == '?' ? '' : params;

    window.history.replaceState({}, "", baseUrl + params);
};

DominikAngerer commented Aug 17, 2017

added params = params == '?' ? '' : params; otherwise a ? would stay even there are no more params left.

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) {
        var updateRegex = new RegExp('([\?&])' + key + '[^&]*');
        var 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;
        }
    }

    // no parameter was set so we don't need the question mark
    params = params == '?' ? '' : params;

    window.history.replaceState({}, "", baseUrl + params);
};
@johnrees

This comment has been minimized.

Show comment
Hide comment
@johnrees

johnrees Oct 5, 2017

If you're not using IE/Edge this can be achieved with URLSearchParams

const params = new URLSearchParams(location.search);
params.set('test', 123);
window.history.replaceState({}, '', `${location.pathname}?${params}`);

johnrees commented Oct 5, 2017

If you're not using IE/Edge this can be achieved with URLSearchParams

const params = new URLSearchParams(location.search);
params.set('test', 123);
window.history.replaceState({}, '', `${location.pathname}?${params}`);
@shr33narayan

This comment has been minimized.

Show comment
Hide comment
@shr33narayan

shr33narayan Feb 19, 2018

@johnrees that's great. 👍

shr33narayan commented Feb 19, 2018

@johnrees that's great. 👍

@dibakarjana

This comment has been minimized.

Show comment
Hide comment
@dibakarjana

dibakarjana Jun 4, 2018

Can anyone please show me how do I implement updateQueryStringParam() in a <button> or <a> or <select> [onChange]?

dibakarjana commented Jun 4, 2018

Can anyone please show me how do I implement updateQueryStringParam() in a <button> or <a> or <select> [onChange]?

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